ES6 Class 语法糖,任然是通过 构造函数 创建实例的
ES5 创建一个类 1 2 3 4 5 6 7 8 9 10 11 12 13 function Point (x, y) { this .x = x this .y = y } Point .prototype .getPosition = function ( ) { return '(' + this .x + ', ' + this .y + ')' } var p1 = new Point (10 , 20 )console .log (p1) console .log (p1.getPosition ())
ES6 Class 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Point { z = 0 constructor (x, y, z) { this .x = x this .y = y this .z = z } getPosition () { return `(${this .x} , ${this .y} )` } static getClassName () { return Point .name } } const p1 = new Point (1 , 2 , 3 )console .log (p1) console .log (p1.getPosition ()) console .log (p1.hasOwnProperty ('x' )) console .log (p1.hasOwnProperty ('getPosition' )) console .log (p1.__proto__ .hasOwnProperty ('getPosition' )) console .log (Point .getClassName ())
constructor 构造函数
当自定义返回值,则 new 出来的对象 p1 不再是 构造函数的实例
constructor 中的属性在构造函数上,外部属性方法则在 原型上1 2 3 4 5 6 7 8 9 10 11 12 13 class Point { z = 0 } class Point { z constructor (x, y, z) { this .x = x this .y = y this .z = z } }
static 声明一个静态方法,实例无法访问,class 本身可以
类只有静态方法,没有静态属性1 2 3 4 5 class Point { static attr = 'staticAttr' } Point .attr = 'staticAttr'
私有方法
只在方法内部,而不暴露给外部
get | set
ES5 set、get1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var info = { _age : 18 , set age (val) { if (val > 18 ) { console .log ('older' ); } else { console .log ('too young too simple' ); } }, get age () { console .log ('my age ?' ); return this ._age } } console .log (info.age ); info.age = 0
ES6 class set | get1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Info { constructor (age) { this ._age = age } set age (newAge) { console .log ('new age is : ' + newAge); this ._age = newAge } get age () { return this ._age } } const info = new Info (18 )console .log (info); info.age = 0
创建 class 如同 js 函数创建两种形式:创建变量再赋值函数体、函数声明形式直接创建函数体
1 2 3 4 5 6 7 class C { constructor () {} } const AClass = class { constructor () {} }
new.target
用于检测方法或构造函数是否是通过 new 被调用的
通过 new 初始化的 函数 或 构造函数中
new.target 返回一个指向构造方法或函数的引用
普通函数 则 返回 undefined
1 2 3 4 5 6 7 8 9 10 11 12 class Point { constructor () { console .log (new .target ); } } const p = new Point ()
super 作为函数使用
代表父类的构造函数 constructor
在使用 extends
继承父类的子类构造函数中,**必须调用一次 super()**,之后才能使用 this
1 2 3 4 5 6 class Child extends Parent { constructor (name, age) { super (name) this .age = age } }
super 在子类的构造函数中作为 方法使用 当子类在 构造函数 中使用 super()
,父类 构造函数中 的 this
则 指向 子类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Parent { constructor () { this .name = 'parent name' console .log (this ); } print () { console .log (this .name ); } } class Child extends Parent { constructor () { super () this .name = 'child name' } childPrint () { super .print () } } const c = new Child ()c.childPrint ()
作为对象
在 普通方法中 super 指向父类的原型对象1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Parent { constructor () { this .type = 'parent' } getName () { return this .type } } Parent .getType = function ( ) { return 'type parent' } class Child extends Parent { getParentName () { console .log ('getParentName: ' + super .getName ()) } getParentType () { console .log ('getParentName: ' + super .getType ()) } } const c = new Child ()c.getParentName () c.getParentType ()
在静态方法中,指向父类1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Parent { constructor () {} } Parent .getType = function ( ) { return 'type parent' } class Child extends Parent { static __getParentType () { console .log ('getParentName: ' + super .getType ()) } } Child .__getParentType ()
ES6 class 和 ES5 构造函数实现 继承 的差异
ES5 先创建子构造函 数的 this
,再将 父构造函数的属性方法 添加到 this
上
ES6 class 则是先从父类 取到实例对象 this
,再调用 super()
之后,再将属性和方法 添加到 this
上