ES6 class小结

classs类定义
class xxx{}
constructor方法
默认会自动添加constructor方法。返回当前实例(this).也可以返回其他对象。
类的实例对象
不同于ES5,在ES6中,不通过关键字new,调用,将会报错。
所有的属性,都定义在自身上,方法都定义在prototype上。
不存在变量提升
Class表达式
const myClass = class xxx{ xxx在代码内不指向}
立执行class let xx = new Class{}(‘参数’)
私有方法
用’_'方式去区分,但还是会被外部,所改变。
另一种方法就是索性将私有方法移出模块,因为模块内部的所有方法都是对外可见的。
还有一种方法是利用Symbol值的唯一性,将私有方法的名字命名为一个Symbol值。
this的指向
call,apply,bind;箭头函数;proxy
Class的继承
使用extends关键字来实现继承。
super(x, y); // 调用父类的constructor(x, y);
子类必须在constructor方法中调用super方法,否则新建实例时会报错。
这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
注意:
ES5的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。
ES6的继承机制完全不同,实质是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this
另一个需要注意的地方是,在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。
这是因为子类实例的构建,是基于对父类实例加工,只有super方法才能返回父类实例。
类的prototype属性和__proto__属性
大多数浏览器的ES5实现之中,每一个对象都有__proto__属性,指向对应的构造函数的prototype属性。Class作为构造函数的语法糖,同时有prototype属性和__proto__属性,因此同时存在两条继承链。
(1)子类的__proto__属性,表示构造函数的继承,总是指向父类。
(2)子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。
class A {
}

class B extends A {
}

B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true

实现原理:
// B的实例继承A的实例
Object.setPrototypeOf(B.prototype, A.prototype);
// B继承A的静态属性
Object.setPrototypeOf(B, A);

setPrototypeOf实现原理:
Object.setPrototypeOf = function (obj, proto) {
obj.proto = proto;
return obj;
}
这两条继承链,可以这样理解:作为一个对象,子类(B)的原型(__proto__属性)是父类(A);作为一个构造函数,子类(B)的原型(prototype属性)是父类的实例。

super 关键字
可以作为函数调用,和对象调用。
注意,super虽然代表了父类A的构造函数,但是返回的是子类B的实例,即super内部的this指的是B,因此super()在这里相当于A.prototype.constructor.call(this)。
函数调用:
作为函数时,super()只能用在子类的构造函数之中,用在其他地方就会报错。
super作为对象时,指向父类的原型对象。

实例的__proto__属性
子类实例的__proto__属性的__proto__属性,指向父类实例的__proto__属性。也就是说,子类的原型的原型,是父类的原型。因此,通过子类实例的__proto__.__proto__属性,可以修改父类实例的行为。
具体的参考的链接

你可能感兴趣的:(ES6)