一、主要區別
-
ES5 的繼承實質上是先創建子類的實例對象, 然后再將父類的方法添加
到 this 上(Parent.apply(this)) . -
ES6 的繼承機制完全不同, 實質上是先創建父類的實例對象 this(所以必
須先調用父類的 super()方法) , 然后再用子類的構造函數修改 this。 -
ES5 的繼承時通過原型或構造函數機制來實現。
-
ES6 通過 class 關鍵字定義類, 里面有構造方法, 類之間通過 extends 關
鍵字實現繼承。 -
子類必須在 constructor 方法中調用 super 方法, 否則新建實例報錯。 因
為子類沒有自己的 this 對象, 而是繼承了父類的 this 對象, 然后對其進行加工。
如果不調用 super 方法, 子類得不到 this 對象。 -
注意 super 關鍵字指代父類的實例, 即父類的 this 對象。
-
注意: 在子類構造函數中, 調用 super 后, 才可使用 this 關鍵字, 否則
報錯。
function 聲明會提升, 但不會初始化賦值。 Foo 進入暫時性死區, 類似于 let、
const 聲明變量。
const bar = new Bar();
// it's ok
function Bar() { this.bar = 42;
}
const foo = new Foo();
// ReferenceError: Foo is not defined
class Foo { constructor() { this.foo = 42; }
}
二、class 聲明內部會啟用嚴格模式。
// 引用一個未聲明的變量 function Bar() {
baz = 42;
// it's ok}const bar = new Bar();
class Foo { constructor() { fol = 42; // ReferenceError: fol is not defined }
}const foo = new Foo();
三、class 的所有方法(包括靜態方法和實例方法) 都是不可枚舉的。
// 引用一個未聲明的變量
function Bar() { this.bar = 42;
}
Bar.answer = function() { return 42;
};
Bar.prototype.print = function() { console.log(this.bar);
};
const barKeys = Object.keys(Bar);
// ['answer']
const barProtoKeys = Object.keys(Bar.prototype);
// ['print']class Foo { constructor() { this.foo = 42; } static answer() { return 42; } print() { console.log(this.foo); }
}
const fooKeys = Object.keys(Foo);
// []
const fooProtoKeys = Object.keys(Foo.prototype);
// []
四、class 的所有方法( 包括靜態方法和實例方法) 都沒有原型對象 prototype, 所以也沒有 constructor
, 不能使用 new 來調用。
function Bar() { this.bar = 42;
}
Bar.prototype.print = function() { console.log(this.bar);
};
const bar = new Bar();
const barPrint = new bar.print(); // it's ok
class Foo { constructor() { this.foo = 42; } print() { console.log(this.foo); }
}
const foo = new Foo();
const fooPrint = new foo.print();
// TypeError: foo.print is not a constructor
必須使用 new 調用 class。
function Bar() { this.bar = 42;
}
// it's ok
const bar = Bar(); class Foo { constructor() { this.foo = 42; }
}
const foo = Foo();
// TypeError: Class constructor Foo cannot be invoked without 'new'
五、class 內部無法重寫類名。
function Bar() { Bar = 'Baz'; // it's ok this.bar = 42;
}
const bar = new Bar();
// Bar: 'Baz'
// bar: Bar {bar: 42} class Foo { constructor() { this.foo = 42; Foo = 'Fol'; // TypeError: Assignment to constant variable }
}
const foo = new Foo();
Foo = 'Fol';
// it's ok