-
原型鏈繼承
-
非常純粹的繼承關係,實例是子類的實例,也是父類的實例
-
父類新增原型方法/原型屬性,子類都能訪問到
-
簡單,易於實現
-
在父類新增的方法和屬性,在任何一個子類事列中都可以訪問,每個子類只能訪問自己子類的方法和屬性,不能訪問
-
-
call繼承(構造繼承)
function Animal(name){
this.name=name||"Animal"
this.sleep=function(){
console.log(this.name+"睡覺")
}
}
Animal.prototype.eat=function(foot){
console.log(this.name+"吃東西"+foot)
}
function Dog(name){
Animal.call(this)
this.name = name
}
var dogone=new Dog('花花')
dogone.sleep()
dogone.eat("骨頭") //這個在原型鏈上面,無法繼承。繼承的是父類中的this指示下的屬性和方法
特點:
-
解決了1中,子類實例共享父類引用屬性的問題
-
創建子類實例時,可以向父類傳遞參數
-
可以實現多繼承(call多個父類對象)
缺點:
-
實例並不是父類的實例,只是子類的實例
-
只能繼承父類的實例屬性和方法,不能繼承原型屬性/方法
-
無法實現函數複用,每個子類都有父類實例函數的副本,影響性能
-
3.拷貝繼承
-
效率較低,內存佔用高(因爲要拷貝父類的屬性)
-
無法獲取父類不可枚舉的方法(不可枚舉方法,不能使用for in 訪問到)
-
原型鏈+call構造繼承
-
function Animal(name){this.name=name||"Animal"this.sleep=function(){console.log(this.name+"睡覺")}}Animal.prototype.eat=function(foot){console.log(this.name+"吃東西"+foot)}function Dog(name){Animal.call(this)this.name=name||'狗狗'}Dog.prototype=new Animal()Dog.prototype.constructor = Dog;var dogone=new Dog('花花')dogone.sleep()dogone.eat("骨頭")var pig=new Dog('等待')pig.sleep()pig.eat("骨頭")console.log(dogone.name)特點:
-
彌補了方式2的缺陷,可以繼承實例屬性/方法,也可以繼承原型屬性/方法
-
既是子類的實例,也是父類的實例
-
不存在引用屬性共享問題
-
可傳參
-
函數可複用
缺點:-
調用了兩次父類構造函數,生成了兩份實例(子類實例將子類原型上的那份屏蔽了)
-
-
function Animal(name){this.name=name||"Animal"this.sleep=function(){console.log(this.name+"睡覺")}}Animal.prototype.eat=function(foot){console.log(this.name+"吃東西"+foot)}function Dog(name){Animal.call(this)this.name=name||'狗狗'}Dog.prototype = createObject(Animal.prototype)Dog.prototype.constructor = Dog;function createObject(o){function fn(){}fn.prototype = o;return new fn;}var dogone=new Dog('花花')dogone.sleep()dogone.eat("骨頭")var pig=new Dog('等待')pig.sleep()pig.eat("骨頭")console.log(dogone.name)