在Javascript中,每個函數都有一個原型屬性prototype指向自身的原型,而由這個函數創建的對像也有一個__proto__屬性指向這個原型,而函數的原型是一個對象,所以這個對像也會有一個__proto__指向自己的原型,這樣逐層深入直到Object物件的原型,這樣就形成了原型鏈。
每個函數都是Function函數建立的對象,所以每個函數也有一個__proto__屬性指向Function函數的原型。這裡要指出的是,真正形成原型鏈的是每個物件的__proto__屬性,而不是函數的prototype屬性,這是很重要的。
基本模式:
var Parent = function(){ this.name = 'parent' ; } ; Parent.prototype.getName = function(){ return this.name ; } ; Parent.prototype.obj = {a : 1} ; var Child = function(){ this.name = 'child' ; } ; Child.prototype = new Parent() ; var parent = new Parent() ; var child = new Child() ; console.log(parent.getName()) ; //parent console.log(child.getName()) ; //child
這種是最簡單實作原型繼承的方法,直接把父類別的物件賦值給子類別建構子的原型,這樣子類別的物件就可以訪問到父類別以及父類別建構子的prototype中的屬性。這種方法的優點很明顯,實現十分簡單,不需要任何特殊的操作;同時缺點也很明顯,如果子類需要做跟父類構造函數中相同的初始化動作,那麼就得在子類構造函數中再重複一次父類別中的動作:
var Parent = function(name){ this.name = name || 'parent' ; } ; Parent.prototype.getName = function(){ return this.name ; } ; Parent.prototype.obj = {a : 1} ; var Child = function(name){ this.name = name || 'child' ; } ; Child.prototype = new Parent() ; var parent = new Parent('myParent') ; var child = new Child('myChild') ; console.log(parent.getName()) ; //myParent console.log(child.getName()) ; //myChild
上面這種情況還只是需要初始化name屬性,如果初始化工作不斷增加,這種方式是很不方便的。因此就有了下面一種改進的方式:借用建構子
var Parent = function(name){ this.name = name || 'parent' ; } ; Parent.prototype.getName = function(){ return this.name ; } ; Parent.prototype.obj = {a : 1} ; var Child = function(name){ Parent.apply(this,arguments) ; } ; Child.prototype = new Parent() ; var parent = new Parent('myParent') ; var child = new Child('myChild') ; console.log(parent.getName()) ; //myParent console.log(child.getName()) ; //myChild
上面這個方法在子類別建構子中透過apply呼叫父類別的建構子來進行相同的初始化工作,這樣不管父類別中做了多少初始化工作,子類別也可以執行同樣的初始化工作。但是上面這種實作還存在一個問題,父類別建構函式被執行了兩次,一次是在子類別建構函式中,一次在賦值子類別原型時,這是很多餘的,所以我們還需要做一個改進:
var Parent = function(name){ this.name = name || 'parent' ; } ; Parent.prototype.getName = function(){ return this.name ; } ; Parent.prototype.obj = {a : 1} ; var Child = function(name){ Parent.apply(this,arguments) ; } ; Child.prototype = Parent.prototype ; var parent = new Parent('myParent') ; var child = new Child('myChild') ; console.log(parent.getName()) ; //myParent console.log(child.getName()) ; //myChild
這樣我們就只需要在子類別建構函式中執行一次父類別的建構函數,同時又可以繼承父類別原型中的屬性,這也比較符合原型的初衷,就是把需要重複使用的內容放在原型中。
以上是javascript原型繼承基本模式用法及改良方式實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!