js--繼承的幾種方法及優缺點

做者:LylBrave 來源:CSDN 原文:blog.csdn.net/qq_25461519…bash

瞭解繼承的前提是瞭解原型鏈。原型鏈是每個實例對象都有一個__proto__屬性(隱式原型),在js內部用來查找原型鏈;每個構造函數都有prototype屬性(顯示原型),用來顯示修改對象的原型,實例.proto=構造函數.prototype=原型。原型鏈的特色就是:經過實例.__proto__查找原型上的屬性,從子類一直向上查找對象原型的屬性,繼而造成一個查找鏈即原型鏈。app

  1. 原型鏈繼承

主要利用sub.prototype = new super, 這樣連通了子類-子類原型-父類。函數

//父類,帶屬性
function Super(){
	this.flag = true;
}
//爲了提升複用性,方法綁定在父類原型屬性上
Super.prototype.getFlag = function() {
	return this.flag;
}
//子類
function Sub() {
	this.subFlag = false;
}
//實現繼承
Sub.prototype = new Super;
//給子類添加子類特有的方法,注意順序在繼承以後
Sub.prototype.getSubFlag = function() {
	return this.sunFlag;
}
//構造實例
var es5 = new Sub;
console.log(es5)
複製代碼

特色:

  • 很是純粹的繼承關係,實例是子類的實例,也是父類的實例
  • 父類新增原型方法/原型屬性,子類都能訪問到
  • 簡單,易於實現

缺點:性能

  • 要想爲子類新增屬性和方法,必需要在new Animal()這樣的語句以後執行,不能放到構造器中
  • 沒法實現多繼承
  • 來自原型對象的引用屬性是全部實例共享的
  • 建立子類實例時,沒法向父類構造函數傳參 。
  1. 構造函數繼承

在構造子類構造函數時內部使用call或apply來調用父類的構造函數。ui

function Super(){
	this.flag = true;
}

function Sub() {
	Super.call(this)//若是父類能夠須要接收參數,這裏也能夠直接傳遞
}

var obj = new Sub();
obj.flag = false;

var obj2 = new Sub();
console.log(obj2.flag)//依然是true,不會相互影響 
複製代碼

特色:this

  • 解決了1中,子類實例共享父類引用屬性的問題
  • 建立子類實例時,能夠向父類傳遞參數
  • 能夠實現多繼承(call多個父類對象)

缺點:es5

  • 實例並非父類的實例,只是子類的實例
  • 只能繼承父類的實例屬性和方法,不能繼承原型屬性/方法
  • 沒法實現函數複用,每一個子類都有父類實例函數的副本,影響性能
  1. 組合繼承

利用構造函數和原型鏈的方法,能夠比較完美的實現繼承spa

function Super(){
	this.flag = true;
}

Super.prototype.getFlag = function() {
	return this.flag;
}

function Sub() {
	this.subFlag = false;
	Super.call(this)
}

Sub.prototype = new Super;
var obj = new Sub();
Sub.prototype.constructor = sub;
Super.prototype.getSubFlag = function() {
	return this.flag;
}
這裏還有個小問題,Sub.prototype = new Super; 會致使Sub.prototype的constructor指向Super;然而constructor的定義是要指向原型屬性對應的構造函數的,Sub.prototype是Sub構造函數的原型,因此應該添加一句糾正:Sub.prototype.constructor = Sub;
複製代碼

特色:.net

  • 彌補了方式2的缺陷,能夠繼承實例屬性/方法,也能夠繼承原型屬性/方法
  • 既是子類的實例,也是父類的實例
  • 不存在引用屬性共享問題
  • 可傳參
  • 函數可複用

缺點:prototype

  • 調用了兩次父類構造函數,生成了兩份實例(子類實例將子類原型上的那份屏蔽了)
  1. 寄生組合繼承

即將sub.prototype=new super改成sub.prototype=Object.creat(supper.prototype),避免了組合繼承中構造函數調用了兩次的弊端

相關文章
相關標籤/搜索