Javascript的繼承和標準的oop繼承有很大的區別,Javascript的繼承是採用原型鏈的技術,每個類別都會將「成員變數」和「成員函數」放到prototype 上,Js 都過superclass將其連結起來,即C.prototype.superclass = C.superclass = P.prototype;
當var c = new C()時,c.__proto__ = C.prototype ;
當c訪問「成員變數」時,如果在__proto__無法取得時,就會到C.prototype查找,如果又不存在,又會到父類的prototype查找,由於只有__proto__ 是物件建立時分配的(每個物件獨立分配),其他都是定義時分配的(每個物件共用),此時,如果存取C.prototype中「成員變數」是物件時,不修改「成員變數」的本身,而是修改「成員變數」對象的成員時,修改的「成員變數」物件的成員就會被所有物件實例共享,這樣就違背類別設計的初衷。
例如:
'class B extends A'.j(function () {
});
});
b1.v.a = 5;
b1.x.a = 5;
var b2 = new B();
console.log(b1.x.a) // 輸出為 5
console.log(b2.x.a) // 輸出為1
console.log(b2.p.a) // 不可用,會提示p不存在
A. 將v 這樣的成員「成員變數」(其本身是物件)不在原型鏈上定義,而是在建構函式中調用,此時,建立物件實例時,就會在物件的__proto__上分配。
B. 原型鏈上只定義只讀的「成員變數」(本身就是物件)
C.jpublic 定義的「成員變數」(本身是物件)中的成員,只是只讀成員,切記不可賦值,否則會在各個實例中共享。