先前我们花了很长的篇幅来说明一个事实
JavaScript中没有类
并从很多方面进行了说明(比如类是通过赋值进行实例化,而JavaScript中的对象是通过原型链关联到另一个对象从而进行委托)
而ES6推出的class关键字
实际上是一个语法糖,只是通过class来把JavaScript中这一行为伪装的更像类,更好理解
但实际上并没有改变JavaScript使用原型链进行关联而不是复制类中属性行为的本质
现在我们来介绍下ES6中的class机制,来看看ES6解决了什么问题
class A {
constructor(name) {
this.name = name;
}
rander() {
console.log(this.name);
}
}
var a = new A("a");
a.rander(); //a
console.log(a.__proto__ === A.prototype); //true
console.log(A.prototype.constructor === A); //true
console.log(a.rander === A.prototype.rander); //true
function A(name) {
this.name = name;
}
A.prototype.rander = function() {
console.log(this.name);
}
var a = new A("a");
a.rander(); //a
console.log(a.__proto__ === A.prototype); //true
console.log(A.prototype.constructor === A); //true
console.log(a.rander === A.prototype.rander); //true
可以看到,这两种模式下得出来的结果是完全等价的
但是明显class语法更简洁,摆脱了杂乱的function和prototype语法
而且使用class进行继承时也更为简洁方便,直接使用extend关键字就可以了(如果用bind来硬绑定函数,那么这个函数不会被像普通函数那样被extends拓展到自类中)
而不需要担心prototype的问题
class A {
constructor(name) {
this.name = name;
}
rander() {
console.log(this.name);
}
}
class B extends A {
constructor(name) {
super(name);
}
}
var b = new B("b");
b.rander();//b
同时我们也可以用super.fun(..)来调用原型链上层的fun方法
构造函数不属于类,所以无法相互引用
但是可以通过super(..)来解决
需要注意的是,class语法无法定义类成员的属性(只能定义方法)
还有一个细微的问题,super的绑定是静态绑定(在定义时就绑定好,而不是在调用时绑定)