class(ES6构造函数的语法糖):
总述:
ES5写法:
父类:
function Animal(){
this._name = "animal";
}
Animal.prototype = {
constructor: Animal,
get name(){
return this._name;
},
sayHi: function(){
console.log("hello! I'm:" + this._name);
}
}
寄生方法生产子类:
function Cat(name){
Animal.call(this);
this._name = name;
}
(function($father){
var Supper = {};
Supper.prototype = $father.prototype;
Cat.prototype = new Supper();
Cat.prototype.constructor = Cat;
}(Animal))
ES6简化了写法,并让对象原型的写法更加清晰、更像面向对象编程的语法
父类:
class Animal{
constuctor(){
this._name = "animal";
} //此处不能加“,”否则会报错,定义构造方法,内部定义的属性为实例属性
//下面开始定义原型属性
get name(){
return this._name;
}
sayHi(){
console.log("hello! I'm:" + this._name);
}
}
子类通过extend继承父类:
class Cat extend Animal{
constructor(name){
super();
this._name = name;
}
}
其中:
Cat拥有了一个在ES5中不具有的__proto__属性:实现方式类似ES5的寄生
Cat.__proto__ === Animal; //true
//Object.setPrototypeOf(Cat, Animal);
Cat.prototype.__proto__ === Animal.prototype; //true
//Object.setPrototypeOf(Cat.prototype, Animal.prototype);
PS: setPrototypeOf可理解为:
function (obj, proto) {
obj.__proto__ = proto;
return obj;
}
super关键字:可当函数、可当对象
作为函数调用:
super作为函数调用时,代表父类的构造函数。ES6要求,子类的构造函数必须执行一次super函数。
class A {}
class B extends A {
constructor() {
super();
}
}
super作为对象在普通方法中,指向父类的原型对象(无法取到实例属性):
class A {
p() {
return 2;
}
}
class B extends A {
constructor() {
super();
console.log(super.p()); // 2
}
}
super作为对象,用在静态方法之中指向父类:
class Parent {
static myMethod(msg) {
console.log('static', msg);
}
myMethod(msg) {
console.log('instance', msg);
}
}
class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);
}
myMethod(msg) {
super.myMethod(msg);
}
}
Child.myMethod(1); // static 1
var child = new Child();
child.myMethod(2); // instance 2
通过super对某个属性赋值,super就是this,赋值的属性会变成子类实例的属性:
class A {
constructor() {
this.x = 1;
}
}
class B extends A {
constructor() {
super();
this.x = 2;
super.x = 3;
console.log(super.x); // undefined
console.log(this.x); // 3
}
}