ES6 class
ES6 class
基本概念
-
类的方法都定义在原型上
-
类的方法是不可枚举的
-
类必须使用 new 来调用(typeof class 名 === 'function') -> 所以说类是构造函数的语法糖
-
类没有变量提升
super 关键字
可以作为函数使用,也可以作为对象使用,其他方式使用 super 的时候会报错 (PS: 直接 console.log(super))
为什么在子类的构造函数中必须要调用父类的构造函数呢?
答:在 ES5 中,继承是先定义子类的 this,然后在子类构造函数内部通过父类构造函数的 call、apply 方法,将父类的属性和方法添加到子类的实例上;但是在 ES6 中的继承,是先有父类的 this,然后在子类的构造函数中修改父类饿 this,也就是说子类没有自己的 this,需要继承父类的 this 才行。
所以在使用 class 实现继承的时候如果在子类内部自己定义了构造方法,那么必须要在 constructor 中使用 this 之前调用 super()函数,否则在实例话子类的时候就会报错
-
在子类的构造函数中通过函数调用 super 代表的是父类的构造函数,调用 super,将相当于执行
Parent.prototype.constructor.call(this)
,返回子类的实例 -
在子类的方法中调用通过对象调用 super,相当于父类的原型对象,但是通过 super 调用父类的方法是,方法内部的 this 指向子类实例
-
在子类中给 super 添加属性,相当于添加到子类实例上
原生构造函数的继承
Array、Object 等
使用构造函数的形式是无法继承原生的构造函数的
原因是 call、apply、bind 方法是无法为原生构造函数绑定 this 的,所以子类是无法拿到父类内部的属性和方法的;而 ES5 的继承原理则是先有子类的 this 然后再通过父类的构造函数来 apply、call 来将父类的属性和方法添加到子类实例上
可以通过 class 的方式继承原生的构造函数
原因是,class 继承的原理就是现有父类的 this,然后在子类的构造函数中先调用 super 来继承父类的 this,再修改父类的 this,所以它可以继承原生构造函数
class 的静态属性和静态方法
在 class 内部直接在属性或者方法之前加上 static 关键字即可
静态属性和方法只能同通过类型来调用
在子类的静态方法中可以通过 super 来调用父类的静态方法
class Foo {
static classMethod() {
return 'hello';
}
}
class Bar extends Foo {
static classMethod() {
return super.classMethod() + ', too';
}
}
Bar.classMethod();
class 的 prototype 和__ptoto__
class A {}
class B extends A {}
此时就有
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
原因是 class 的继承是通过下面的方式实现的
class A {}
class B {}
// B 的实例继承 A的实例
Object.setPrototypeOf(B.protorype, A.prototype);
// B 继承 A的静态属性
Object.setPrototypeOf(B, A)
Object.setPrototypeOf = function(obj, proto) {
obj.__proto__ = proto;
return obj;
}
new.target
new 是让构造函数生成实例的命令。ES6 为 new 指令引入了一个 new.target 属性,它返回的是 new 关键字作用于的构造函数。
如果函数不是通过 new 来调用的,则 new.target 的值就是 undefined