我的理解:繼承通俗地講就是子代擁有了父代的比如:地位,金錢,房產(chǎn)等等。在js中伞鲫,繼承就是讓一個對象擁有另一個對象的屬性和方法。下面就來談?wù)勗鯓訉崿F(xiàn)繼承侨核。
(Father代表父類構(gòu)造函數(shù),Son代表子類構(gòu)造函數(shù)灌灾,默認構(gòu)造函數(shù)的方法都是寫在原型中搓译,實例化對象共享原型中的方法,避免了內(nèi)存空間的浪費)
1紧卒,原型鏈繼承 (有兩種實現(xiàn)方式)
(1)Son.prototype = Father.prototype
弊端:Son.prototype.constructor 指向Father,需要手動更改為Son 侥衬;Son的實例化對象只能繼承Father原型中的方法诗祸,無法繼承Father本身的屬性跑芳。
(2)Son.prototype = new Father()
弊端:Son.prototype.constructor 指向Father,需要手動更改為Son;Son的實例化對象共享Father自身的引用類型屬性直颅。什么意思呢博个?下面舉個栗子:
function Father(){? this.name = "zs" ; this.arr = [1,2,3] }
function Son(){? ?}??
Son.prototype = new Father()
var s1 = new Son(), s2 = new Son();
s1.arr.push(5);
console.log(s1.arr)--------> [1,2,3,5]
console.log(s2.arr)--------->[1,2,3,5]
看了這里例子就明白了,Son的實例化對象s1,s2繼承了Father的屬性arr,但是s1,s2是同時指向這一屬性的功偿。
2盆佣,借助構(gòu)造函數(shù)繼承
function Father(){ this.name = "zs"; this.age=38 };
function Son(){? ?Father.call( this) / Father.apply(this)? }
弊端:Son只能繼承Father自身的屬性往堡,而無法繼承Father原型中的方法。
3共耍,組合式繼承
將原型鏈繼承與構(gòu)造函數(shù)結(jié)合起來
function Father(){ this.name="zs";this.age=38 }
Father.prototype.sayHi = function(){? ?alert("hello")? ?}
function Son(){? ?Father.call(this)? }
Son.prototype = new Father()
var s = new Son() ;
弊端:通過Father.call() 和 new Father() ,父類構(gòu)造函數(shù)Father被調(diào)用了兩次虑灰。
4,原型式繼承
function createObj(o){? ?function F(){ }? F.prototype=o ; return new F()? }
var obj = { name:"zs" , age:18, sayHi:function(){ }? }
var newObj = createObj( obj );
newObj繼承了obj的屬性和方法痹兜,但是同樣出現(xiàn)了共享父類中引用類型屬性的問題穆咐。
5,經(jīng)典繼承(Es5中的新語法:存在兼容性問題字旭,需要做瀏覽器的能力檢測)
function create(obj){??
if(Object.create){? return Object.create(obj)? }??
else { function F(){ }? F.prototype=o ; return new F() }
}
6,寄生式繼承(類似于原型式繼承)
function createObj(o){? function F(){ }? F.prototype=o ; return new F()? }
function createObj2(o){? var obj = createObj(o) ; obj.sayHi = function(){? }? return obj }
var obj = { name:"zs" , age:18, sayHi:function(){ }? }
var newObj = createObj2(obj)
newObj繼承了obj的屬性和方法对湃,但是同樣出現(xiàn)了共享父類中引用類型屬性的問題。
7,寄生組合式繼承(組合繼承+寄生繼承)
function createObj(o){? function F(){ }? F.prototype=o ; return new F()? }
function inheritPrototype(Child, Father) {
var prototype = object(Father.prototype);//創(chuàng)建對象
prototype.constructor = Child;//增強對象
Child.prototype = prototype;//指定對象? ?}
function Father(name) {
this.name = name;
this.arr = [1, 2, 3, 4];? ? }
Father.prototype.sayName = function () {? console.log("父類原型" + this.name);? }
function Child(name, age) {? Father.call(this, name);? ?this.age = age;? ?}
inheritPrototype(Child, Father)
Child.prototype.sayAge = function () {? ?console.log(this.age);? ?}
var child1 = new Child() , child2 = new Child();
child1.arr.push(5) ------> [1,2,3,4,5]
child2.arr ------> [1,2,3,4].
優(yōu)點:可以多重繼承 解決兩次調(diào)用? 解決實例共享引用類型的問題 原型鏈保持不變