大多數瀏覽器的 ES5 實現之中,每一個對象都有__proto__
屬性,指向對應的構造函數的prototype
屬性。Class 作為構造函數的語法糖,同時有prototype
屬性和__proto__
屬性,因此同時存在兩條繼承鏈。
(1)子類的__proto__
屬性,表示構造函數的繼承,總是指向父類。
(2)子類prototype
屬性的__proto__
屬性,表示方法的繼承,總是指向父類的prototype
屬性。
class A {}class B extends A {}B.__proto__ === A // trueB.prototype.__proto__ === A.prototype // true
上面代碼中,子類B
的__proto__
屬性指向父類A
,子類B
的prototype
屬性的__proto__
屬性指向父類A
的prototype
屬性。
類相當于實例的原型, 所有在類中定義的方法, 都會被實例繼承。 如果在一個方法前, 加上static關鍵字, 就表示該方法不會被實例繼承, 而是直接通過類來調用, 這就稱為“ 靜態方法”。
class Animal {constructor(name, age) {//實例的私有屬性this.name = namethis.age = agereturn console.log('實例屬性')}test=['hello'] //實例私有屬性,即使寫在constructor外面,也是實例屬性。animalFun() {console.log('Animal實例方法');}static animalAttr = 'Animal靜態屬性'static animalStaFun() {console.log('Animal靜態方法');}}class Dog extends Animal {constructor(name, age, color, weight) {super(name, age)this.color = colorthis.weight = weight}}// 繼承了Animal類的實例屬性和實例方法let dog = new Dog('二狗', 1, 'black', '10kg')console.log(dog);dog.animalFun()// 繼承Animal類的靜態屬性和靜態方法console.log(Dog.animalAttr);Dog.animalStaFun()console.log(Dog.prototype.__proto__ === Animal.prototype);console.log(dog.__proto__.__proto__ === Animal.prototype);console.log(Dog.__proto__ === Animal);// 實例方法和實例屬性寫在哪// 實例可以調用的方法和屬性// 靜態方法和靜態屬性寫在哪// 類本身調用的方法和屬性輸出為:實例屬性Dog { name: '二狗', age: 1, color: 'black', weight: '10kg' }Animal實例方法Animal靜態屬性Animal靜態方法truetruetrue
注意:靜態屬性與靜態方法由類構造函數調用,即上文中的Dog,
實例屬性與實例方法由實例對象調用,即上文中的dog。