js繼承的概念
1.通過原型鏈方式實現(xiàn)繼承(對象間的繼承)
?2.類式繼承(構造函數(shù)間的繼承)?
由于js不像Java那樣是真正面向?qū)ο蟮恼Z言,js是基于對象的,它沒有類的概念。所以,要想實現(xiàn)繼承,可以用js的原型prototype機制或者用apply和call方法去實現(xiàn)。
原型鏈
構造函數(shù)、原型、實例的關系:
每個構造函數(shù)都有一個原型對象(prototype),原型對象都包含一個指向構造函數(shù)的指針(constructor),而實例都包含一個指向原型對象的內(nèi)部指針(__proto__)。
假如我們讓原型對象等于另一個類型的實例,結果會怎么樣呢?顯然,此時的原型對象將包含一個指向另一個原型的指針,相應地,另一個原型中也包含一個指向一個構造函數(shù)的指針。假如另一個原型又是另一個類型的實例,那么上述關系依然成立,如此層層遞進,就構成了實例與原型的鏈條。這就是所謂原型鏈的基本概念。
(每個對象都有一個內(nèi)部屬性__proto__屬性,屬性的值可以是一個對象,也可以是null.如果它的值是一個對象,則這個對象也一定有自己的原型.這樣就形成了一條線性的鏈,我們稱之為原型鏈)
通過原型鏈方式實現(xiàn)繼承
function Parent() {? ? ? ? ?
?? this.hobby="play";? ? ??
? }? ? ? ?
?Parent.prototype.showHobby=function () {? ? ??
? ? ? return this.hobby;? ? ?
?? }? ? ?
?? function Son() {? ? ?
?? ? ? this.sonhobby="eat";? ?
?? ? }? ? ? ? //實現(xiàn)繼承? ,繼承Parent? ? ?
?? Son.prototype=new Parent();? ??
? ? Son.prototype.showSonhobby=function () {? ? ??
? ? ? return this.sonhobby;? ??
? ? }? ??
? ? var obj=new Son();? ? ?
?? alert(obj.showHobby())??
? ? ? for(var i in obj){? ??
? ? ? ? document.write(i+"---"+obj[i]+"<br>"); ? ??
?? }
實現(xiàn)的本質(zhì)是重寫原型對象,代之以一個新類型的實例。
換句話說,原來存在于Parent的實例中的所有屬性和方法,現(xiàn)在也存在于Son.prototype中了。在確定了繼承關系之后,我們給Son.prototype添加了一個新的方法。
要注意,obj.constructor現(xiàn)在指向的是Parent,這是因為原來Son.prototype中的constructro被重寫了的緣故。

確定原型和實例的關系
可以通過兩種方式來確定原型和實例之間的關系。
操作符instanceof和isPrototypeof()方法:
1.instanceof? 只要用這個操作符來測試實例與原型鏈中出現(xiàn)過的構造函數(shù),結果就會返回true.
alert(obj instanceof Object)? ? ? ? //true
alert(obj instanceof Son);? ? ? ? ? //true
alert(obj instanceof Parent);? ? ? ? //true
2.isPrototypeOf()? 只要原型鏈中出現(xiàn)過的原型,都可以說是該原型鏈所派生的實例的原型,因此也會返回true;
.alert(Object.prototype.isPrototypeOf(obj))? ? ? ? //true
alert(Son.prototype.isPrototypeOf(obj));? ? ? ? ? //true
alert(Parent.prototype.isPrototypeOf(obj));? ? ? ? //true
借用構造函數(shù)(類式繼承)
function Parent(age){
this.name = ['mike','jack','smith'];
this.age = age;
}
function Child(age){
Parent.call(this,age);? //Parent.apply(this,age);
}
var test = new Child(21);
alert(test.age);//21
alert(test.name);//mike,jack,smith test.name.push('bill'); alert(test.name);//mike,jack,smith,bill
組合式繼承
組合式繼承是比較常用的一種繼承方法,其背后的思路是:
使用原型鏈實現(xiàn)對原型屬性和方法的繼承,而通過借用構造函數(shù)來實現(xiàn)對實例屬性的繼承。這樣,既通過在原型上定義方法實現(xiàn)了函數(shù)復用,又保證每個實例都有它自己的屬性。
function Parent(age){
this.name = ['mike','jack','smith'];
this.age = age;
}
Parent.prototype.run = function () {
return this.name + ' are both' + this.age;
};
function Child(age){
Parent.call(this,age);//對象冒充,給超類型傳參
}
Child.prototype = new Parent();//原型鏈繼承
var test = new Child(21);//寫new Parent(21)4也行
alert(test.run());//mike,jack,smith are both21