JavaScript并不提供原生的繼承機制惨驶,我們自己實現(xiàn)的方式很多透绩,介紹一種最為通用的
通過上面定義我們可以看出我們?nèi)绻麑崿F(xiàn)了兩點的話就可以說我們實現(xiàn)了繼承
得到一個類的屬性
得到一個類的方法
我們分開討論一下羊瘩,先定義兩個類
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.printName = function(){
console.log(this.name);
};
function Male(age){
this.age = age;
}
Male.prototype.printAge = function(){
console.log(this.age);
};
屬性的獲取
對象屬性的獲取是通過構(gòu)造函數(shù)的執(zhí)行江解,我們在一個類中執(zhí)行另外一個類的構(gòu)造函數(shù)坟冲,就可以把屬性賦值到自己內(nèi)部靠汁,但是我們需要把環(huán)境改到自己的作用域內(nèi),需要用到call方法
function Male(name, sex, age){
Person.call(this, name, sex);
this.age = age;
}
Male.prototype.printAge = function(){
console.log(this.age);
};
實例化結(jié)果看看:
var m = new Male('Byron', 'male', 26);
console.log(m.sex); // "male"
方法獲取
我們知道類的方法都定義在了prototype里面皆疹,所以只要我們把子類的prototype改為父類的prototype的備份就好了
Male.prototype = Object.create(Person.prototype);
防止方法被覆蓋疏橄,得這么寫:
function Male(name, sex, age){
Person.call(this, name, sex);
this.age = age;
}
Male.prototype = Object.create(Person.prototype);
Male.prototype.printAge = function(){
console.log(this.age);
};
prototype對象有一個屬性constructor指向其類型,因為我們復(fù)制的父元素的prototype略就,這時候constructor屬性指向是不對的捎迫,導(dǎo)致我們判斷類型出錯, 因此我們需要再重新指定一下constructor屬性到自己的類型。補上這一句:
Male.prototype.constructor = Male
最終是這個樣子的:
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.printName = function(){
console.log(this.name);
};
function Male(name, sex, age){
Person.call(this, name, sex);
this.age = age;
}
Male.prototype = Object.create(Person.prototype);
Male.prototype.constructor = Male;
Male.prototype.printAge = function(){
console.log(this.age);
};
這樣就實現(xiàn)了最終的繼承表牢。
hasOwnProperty
hasOwnPerperty是Object.prototype的一個方法窄绒,可以判斷一個對象是否包含自定義屬性而不是原型鏈上的屬性,hasOwnProperty是JavaScript中唯一一個處理屬性但是不查找原型鏈的函數(shù)
m.hasOwnProperty('name'); // true
m.hasOwnProperty('printName'); // false
Male.prototype.hasOwnProperty('printAge'); // true