- 如果實現(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),這就要借助函數(shù)call了
改造一些Male
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);
這里我們通過Object.createclone了一個新的prototype而
不是直接把Person.prtotype直接賦值,因為引用關系,這樣會導致后續(xù)修改子類的prototype也修改了父類的prototype,因為修改的是一個值另外Object.create是ES5方法,之前版本通過遍歷屬性也可以實現(xiàn)淺拷貝
-這樣做需要注意一點就是對子類添加方法,必須在修改其prototype之后,如果在之前會被覆蓋掉
Male.prototype.printAge = function(){
console.log(this.age);
};
Male.prototype = Object.create(Person.prototype);
這樣的話,printAge方法在賦值后就沒了,因此得這么寫
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指向其類型,因為我們復制的父元素的prototype,這時候constructor屬性指向是不對的,導致我們判斷類型出錯
Male.prototype.constructor; //Person
因此我們需要再重新指定一下constructor屬性到自己的類型
最終方案
- 我們可以通過一個函數(shù)實現(xiàn)剛才的內(nèi)容
function inherit(superType, subType){
var _prototype = Object.create(superType.prototype);
_prototype.constructor = subType;
subType.prototype = _prototype;
}
使用方式
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;
}
inherit(Person, Male);
// 在繼承函數(shù)之后寫自己的方法,否則會被覆蓋
Male.prototype.printAge = function(){
console.log(this.age);
};
var m = new Male('Byron', 'm', 26);
m.printName();
這樣我們就在JavaScript中實現(xiàn)了繼承
hasOwnProperty
繼承之后Male的實例也有了Person的方法,那么怎么判斷某個是自己的還是父類的?
hasOwnPerperty是Object.prototype的一個方法,可以判斷一個對象是否包含自定義屬性而不是原型鏈上的屬性,hasOwnProperty是JavaScript中唯一一個處理屬性但是不查找原型鏈的函數(shù)
m.hasOwnProperty('name'); // true
m.hasOwnProperty('printName'); // false
Male.prototype.hasOwnProperty('printAge'); // true