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個結論 拖拽層在目標層上部活動時不會碰撞 拖拽層在目標層左邊活動時不會碰撞 拖拽層在目標層右邊活動時不會碰撞 拖拽層在目標層下邊活動時不會碰撞 二 先來...