JS繼承原理剖析

2021-09-29 09:18:53 字數 4484 閱讀 1656

1、原型鏈繼承

建構函式、原型和例項之間的關係:每個建構函式都有乙個原型物件,原型物件都包含乙個指向建構函式的指標,而例項都包含乙個原型物件的指標。

繼承的本質就是複製,即重寫原型物件,代之以乙個新型別的例項。

function

supertype()

supertype.prototype.

getsupervalue

=function()

function

subtype()

// 這裡是關鍵,建立supertype的例項,並將該例項賦值給subtype.prototype

subtype.prototype =

newsupertype()

; subtype.prototype.

getsubvalue

=function()

var instance =

newsubtype()

;console.

log(instance.

getsupervalue()

);// true

原型鏈方案存在的缺點:多個例項對引用型別的操作會被篡改。

function

supertype()

function

subtype()

subtype.prototype =

newsupertype()

; ->例項物件的賦值,supertype->建構函式,new supertype()._proto_ = supertype.prototype

var subinstance =

newsubtype()

;subinstance.colors.

push

("black");

console

(subinstance.colors)

;//"red,blue,green,black"

var sub2instance =

newsubtype()

; console.

log(sub2instance.colors)

;//"red,blue,green,black"

2、借用建構函式繼承

使用父類的建構函式來增強子類例項,等同於複製父類的例項給子類(不使用原型)

function

supertype()

function

subtype()

var instance1 =

newsubtype()

;instance1.color.

push

("black");

alert

(instance1.color)

;//"red,green,blue,black"

var instance2 =

newsubtype()

;alert

(instance2.color)

;//"red,green,blue"

//缺點:只能繼承父類的例項屬性和方法,不能繼承原型屬性/方法;無法實現復用,每個子類都有父類例項函式的副本,影響效能

3、組合繼承

組合上述兩種方法就是組合繼承。用原型鏈實現對原型屬性和方法的繼承,用借用建構函式技術來實現例項屬性的繼承。

function

supertype

(name)

supertype.prototype.

sayname

=function()

;function

subtype

(name, age)

// 繼承方法, 構建原型鏈, 第一次呼叫supertype()

subtype.prototype =

newsupertype()

;// 重寫subtype.prototype的constructor屬性,指向自己的建構函式subtype

subtype.prototype.constructor = subtype;

subtype.prototype.

sayage

=function()

;var instance1 =

newsubtype

("nicholas",29

);instance1.colors.

push

("black");

alert

(instance1.colors)

;//"red,blue,green,black"

instance1.

sayname()

;//"nicholas";

instance1.

sayage()

;//29

var instance2 =

newsubtype

("greg",27

);alert

(instance2.colors)

;//"red,blue,green"

instance2.

sayname()

;//"greg";

instance2.

sayage()

;//27

4、原型式繼承

利用乙個空物件作為中介,將某個物件直接賦值給空物件建構函式的原型。

function

object

(obj)

f.prototype = obj;

return

newf()

;}

object()對傳入其中的物件執行了一次淺複製,將建構函式f的原型直接指向傳入的物件

var person =

;var anotherperson =

object

(person)

;anotherperson.name =

"greg"

;anotherperson.friends.

push

("rob");

var yetanotherperson =

object

(person)

;yetanotherperson.name =

"linda"

;yetanotherperson.friends.

push

("barbie");

alert

(person.friends)

;//"shelby,court,van,rob,barbie"

缺點:

原型鏈繼承多個例項的引用型別屬性指向相同,存在篡改的可能。

無法傳遞引數

另外,es5中存在object.create()的方法,能夠代替上面的object方法。

5、寄生組合式繼承

結合借用建構函式傳遞引數和寄生模式實現繼承

function

createanother

(original)

;return clone;

}

function

inheritprototype

(subtype, supertype)

// 父類初始化例項屬性和原型屬性

function

supertype

(name)

supertype.prototype.

sayname

=function()

;// 借用建構函式傳遞增強子類例項屬性(支援傳參和避免篡改)

function

subtype

(name, age)

// 將父類原型指向子類

inheritprototype

(subtype, supertype)

;// 新增子類原型屬性

subtype.prototype.

sayage

=function()

var instance1 =

newsubtype

("xyc",23

);var instance2 =

newsubtype

("lxy",23

);instance1.colors.

push

("2");

// ["red", "blue", "green", "2"]

instance1.colors.

push

("3");

// ["red", "blue", "green", "3"]

這個例子的高效率體現在它只呼叫了一次supertype 建構函式,並且因此避免了在subtype.prototype 上建立不必要的、多餘的屬性。於此同時,原型鏈還能保持不變;因此,還能夠正常使用instanceof 和isprototypeof()

js繼承原理

首先要理解 建構函式 存在乙個prototype 指向他的原型物件 原型物件其實就是一塊空間,可以是物件的實列 實列 存在乙個 prototype 指向他的建構函式的原型物件一般 proto 表示 new 來建立的實列是開闢乙個新的空間所以是無法共享元素的但是new 的建構函式的 prototype...

js繼承的原理

js中的物件和函式最頂級的兩個類為object和function,任何由我們定義的函式或物件都是這兩個類的子類 也就是說js中的一切都是物件.一.函式物件和一般物件 物件分為函式物件和一般物件,函式物件,比如function f var f function var f new function a...

JS剖析正方形物體碰撞原理

最近在做乙個拖拽排序的專案,其中就有個檢測兩個物件之間是否發生碰撞,網上有好多寫好的 但講原理的沒有找到幾個,下面就剖析一下是如何實現碰撞的!一 4個結論 拖拽層在目標層上部活動時不會碰撞 拖拽層在目標層左邊活動時不會碰撞 拖拽層在目標層右邊活動時不會碰撞 拖拽層在目標層下邊活動時不會碰撞 二 先來...