構造函數的繼承
今天介紹一下對象之間繼承的五種方式
下面有兩個構造函數:
function Animal(){ this.species = "動物"; }
function Cat(name,color){ this.name = name; this.color = color; }
現在我們怎麽使得Cat繼承Animal?
以下我們用五種方法來實現繼承
一、 構造函數綁定(call、apply)
這種方法直接簡單,使用call或apply直接將父對象的構造函數綁定在子對象上
function Cat(name,color){ Animal.apply(this, arguments); this.name = name; this.color = color; } var cat1 = new Cat("大毛","黃色"); alert(cat1.species); // 動物
二、 prototype模式
javaScript規定,每一個構造函數都會有一個prototype屬性,指向另一個對象,而這個對象所有的方法和屬性,都會被
構造函數的實例繼承。
如果Cat的prototype對象,指向Animal的一個實例,那麽所有Cat的實例,也就理所當然的能夠繼承Animal了。
Cat.prototype = newAnimal(); Cat.prototype.constructor = Cat; var cat1 = new Cat("大毛","黃色"); alert(cat1.species); // 動物
我們來分析一下這段代碼。
Cat.prototype = new Animal();這行代碼讓Cat的prototype對象指向了一個Animal的實例。
它相當於完全刪除了prototype對象原來的值,然後賦予一個新的值。
但是,這樣會有一個問題出現,就是Cat.prototype,constructor會指向Animal,所以,
Cat.prototype.constructor = Cat;這行代碼讓Cat.prototype的constructor指向Cat,不至於導致繼承鏈的紊亂。
三、 直接繼承prototype
我們可以把Animal對象中不變的屬性寫入Animal.prototype。這時候,我們就可以直接去Animal.prototype。
我們將Animal對象改寫一下:
function Animal(){ } Animal.prototype.species = "動物";
然後,將Cat的prototype對象指向Animal的prototype對象。
Cat.prototype = Animal.prototype; Cat.prototype.constructor = Cat; var cat1 = new Cat("大毛","黃色"); alert(cat1.species); // 動物
雖然這種方法實現了繼承,但是,當我們修改Cat.prototype時,會反映到Animal.prototype。
還有一個問題就是當添加了Cat.prototype.constructor = Cat;這行代碼的時候,我們會發現
Animal.prototype.constructor = Cat,把Animal的constructor 也修改了,所以這種方法不是很完美。
四、 利用空對象作為中介
利用一個空的對象作為一個中介
var F = function(){}; F.prototype = Animal.prototype; Cat.peotorype = new F(); Cat.prototype.constructor = Cat;
F是個空對象,幾乎不占用內存,這時候修改了Cat.prototype的屬性。
我們將上面的方法,封裝成一個函數,便於使用。
fnntion extend(Child,Parent){ var F = function(){}; F.prototype = Parent.prototype; Child.peotorype = new F(); Child.prototype.constructor = Child; Child.uber = Parent.prototype; }
使用方法:
extend(Cat,Animal); var cat1 = new Cat("大毛","黃色"); alert(cat1.species); // 動物
控對象繼承,可以說是一種很完美的繼承方法,推薦大家使用。
五、 拷貝繼承
如果把父對象的所有屬性和方法,拷貝進子對象,也能夠實現繼承。
首先,還是把Animal的所有不變屬性,都放到它的prototype對象上。
function Animal(){} Animal.prototype.species = "動物";
然後,再寫一個函數,實現屬性拷貝的目的。
function extend2(Child, Parent) { var p = Parent.prototype; var c = Child.prototype; for (var i in p) { c[i] = p[i]; } c.uber = p; }
使用方法:
extend2(Cat, Animal); var cat1 = new Cat("大毛","黃色"); alert(cat1.species); // 動物
構造函數的繼承