1、ES6中的类完全可以看作构造函数的另一种写法。
class Point{ //.. } typeof Point //‘function‘ Point === Point.prototype.constructor // true
类的数据类型就是函数,类本身指向构造函数
class Point{ //.. constructor(){ } toString(){ } toValue(){ } } // 等同于 Point.prototype = { constructor(){}, toString(){}, toValue(){} }
Object.assign方法可以很方便的一次向类添加多个方法。
Object.assign(Point.prototype,{
toString(){},
toValue(){}
})
类的内部定义的所有方法都是不可枚举的
2、constructor
constructor 方法是类的默认方法,通过new命令生成对象实例时自动调用该方法。一个类必须有constructor方法,如果没有显示定义,空的constructor会被添加。
3、实例对象
使用new
类的所有实例共享一个原型对象
var p1 = new Point(2,3); var p2 = new Point(3,3); p1.__proto__ = p2.__proto__
4、不存在变量提升
class不存在变量提升
5、class 的继承
class 之间可以通过extends关键字实现继承
class colorpoint extends point {}
super 关键字,指代父类的实例(即父类的this对象)
子类必须在constructor方法中调用super方法,否则新建实例时会报错,因为子类没有自己的this对象。
ES6的继承机制完全不同,实质上是先创造父类的实例对象this,然后再用子类的构造函数修改this
只有调用super之后,才可以使用this关键字
6、类的prototype属性和__proto__属性
在ES5中,每一个对象都有__proto__属性,指向对应的构造函数的prototype属性。
ES5:
1.对象有属性__proto__,指向该对象的构造函数的原型对象。
2.方法除了有属性__proto__,还有属性prototype,prototype指向该方法的原型对象。
class 作为构造函数的语法糖,同时有prototype属性和__proto__属性
1、子类的__proto__属性表示构造函数的继承,总是指向父类。
2、子类prototype 属性的__proto__属性表示方法的继承,总是指向父类的prototype属性。
class B extends A { } B.__proto__ === A//true B.prototype.__proto__ === A.prototype // true
// B 的实例继承 A 的实例
Object.setPrototypeOf(B.prototype, A.prototype);
// 等同于 B.prototype.__proto__ = A.prototype;
// B 的实例继承 A 的静态属性
Object.setPrototypeOf(B, A); // 等同于 B.__proto__ = A;
这两条继承链,可以这样理解:作为一个对象,子类(B
)的原型(__proto__
属性)是父类(A
);作为一个构造函数,子类(B
)的原型对象(prototype
属性)是父类的原型对象(prototype
属性)的实例。
7、实例的__proto__属性
子类实例的__proto__
属性的__proto__
属性,指向父类实例的__proto__
属性。也就是说,子类的原型的原型,是父类的原型
var p1 = new Point(2, 3); var p2 = new ColorPoint(2, 3, ‘red‘); p2.__proto__ === p1.__proto__ // false p2.__proto__.__proto__ === p1.__proto__ // true
8、class 的静态方法
如果在一个方法前加上static关键字,就表示该方法不会被实例继承,而是直接通过类调用,称为静态方法。
父类的静态方法可以被子类继承