【原型和原型鏈】類和繼承
阿新 • • 發佈:2018-12-31
一、定義“類” ——建構函式
我們知道,JavaScript中沒有類的概念,我們只是通過函式來模仿類的行為,我們將它稱之為
建構函式
建構函式
分兩類,原生建構函式和自定義建構函式。原生建構函式
像Array、Object,是執行環境自動提供的;自定義建構函式
是我們自己來建立的
當你想用相同的屬性和方法建立多個相似的物件時,建構函式是非常有用的。
定義建構函式的方法:
function Animal(name){
//此判斷是使用時預設new關鍵詞時的安全策略
if(!(this instanceof Animal)){
return new Animal(name);
}
this.name = name;
}
Animal.prototype = {
eat: function(){
console.log('I am eating');
}
}
var dog = new Animal();
dog.eat(); // I am eating
在呼叫new創造例項時,做了下面幾件事:
建構函式中的this指向當前出發執行的物件,即dog,所以在dog本身添加了屬性name
dog的
__proto__
指向Animal的prototype
,對dog.__proto__
prototype
的變化,從而使得所有由Animal創造的例項__proto__
中的屬性改變(引用型別,全都指向同一地址)dog的
constructor
屬性指向Animal本身,因為dog的constructor
指向Animal本身,所以我們可以通過instanceof來判斷dog是否為Animal的例項,但是constructor可以被改寫,所以通過instanceof來判斷不一定準確
二、繼承
在JavaScript中一切都是物件,當我們談到繼承,其實是物件從物件中的繼承,而不是類從類中的繼承
很多時候我們在建立多個具有相同屬性的例項時,可能有幾個具有自己特有的屬性,所以我們需要先繼承公共建構函式中的屬性,然後改寫自己特有的屬性
繼承寫法:
function Animal(name){
if(!(this instanceof Animal)){
return new Animal(name);
}
this.name = name;
}
Animal.prototype = {
eat: function(){
console.log('I am eating');
}
}
function Mammalia(name, age){
this.name = name;
this.age = age;
}
Mammalia.prototype = new Animal();
var dog = new Mammalia('hashiqi', 5);
最後生成的原型鏈如圖:
三、ES6中的class
class
一直是 JS 的關鍵字(保留字),但是一直沒有正式使用,在ES6中終於使用到了它,通過class來定義建構函式,從語法上更加符合面向物件的寫法
對目錄一中程式碼的改寫:
class Animal {
constructor(name){
this.name = name;
}
eat(){
console.log('I am eating');
}
}
var dog = new Animal();
dog.eat(); // I am eating
對目錄二繼承程式碼的改寫:
class Animal {
constructor(name){
this.name = name;
}
eat(){
console.log('I am eating');
}
}
class Mammalia extends Animal {
constructor(name, age){
super(name);
this.name = name;
this.age = age;
}
}
var dog = new Mammalia('hashiqi', 5);
注意:
子類
的constructor一定要執行super()
,以呼叫父類
的constructor- 繼承的關鍵詞是
extends
,不要忘記s class
是ES6提供的一種語法糖
,其內部實現原理還是一樣的