一席里、什么是"非構造函數(shù)"的繼承梧躺?
比如,現(xiàn)在有一個對象亏吝,叫做"中國人"店诗。
var Chinese = {
nation:'中國'
};
還有一個對象裹刮,叫做"醫(yī)生"。
var Doctor ={
career:'醫(yī)生'
}
要怎樣才能讓"醫(yī)生"去繼承"中國人"庞瘸?
這里兩個對象都是普通對象捧弃,而非構造函數(shù),無法用構造函數(shù)方法實現(xiàn)"繼承"擦囊。
二违霞、object()方法
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
這里的object()函數(shù),就是把子對象的prototype屬性瞬场,指向父對象买鸽,從而使得子對象與父對象連在一起。
使用時贯被,先在父對象的基礎上眼五,生成子對象:
var Doctor = object(Chinese);
然后,再加上子對象本身的屬性:
Doctor.career = '醫(yī)生';
這時彤灶,子對象已繼承了父對象的屬性看幼。
alert(Doctor.nation); //中國
三、淺拷貝
把父對象的屬性幌陕,全部拷貝給子對象桌吃,也能實現(xiàn)繼承。
下面這個函數(shù)苞轿,就是在做拷貝:
function extendCopy(p) {
var c = {};
for (var i in p) {
c[i] = p[i];
}
c.uber = p;
return c;
}
使用的這樣寫:
var Doctor = extendCopy(Chinese);
Doctor.career = '醫(yī)生';
alert(Doctor.nation); // 中國
但是茅诱,這樣拷貝有個問題:如果父對象的屬性等于數(shù)組或另一個對象,那么實際上搬卒,子對象獲得的只是一個內存地址瑟俭,而非真正拷貝,因此存在父對象被篡改的可能契邀。
現(xiàn)在給Chinese添加一個"出生地"屬性摆寄,它的值是一個數(shù)組。
Chinese.birthPlaces = ['北京','上海','廣州'];
通過extendCopy()函數(shù)坯门,Doctor繼承了Chinese微饥。
var Doctor = extendCopy(Chinese);
然后,我們?yōu)镈octor的"出生地"添加一個城市:
Doctor.birthPlaces.push('深圳');
此時古戴,Chinese的"出生地"也被修改了欠橘?
alert(Doctor.birthPlaces); //北京, 上海, 廣州, 深圳
alert(Chinese.birthPlaces); //北京, 上海, 廣州, 深圳
所以,extendCopy()只是拷貝基本類型的數(shù)據(jù)现恼,我們把這種拷貝叫做"淺拷貝"肃续。這是早期jQuery實現(xiàn)繼承的方式。
四叉袍、深拷貝
所謂"深拷貝"始锚,就是能夠實現(xiàn)真正意義上的數(shù)組和對象的拷貝。它的實現(xiàn)并不難喳逛,只要遞歸調用"淺拷貝"就行了瞧捌。
function deepCopy(p, c) {
var c = c || {};
for (var i in p) {
if (typeof p[i] === 'object') {
c[i] = (p[i].constructor === Array) ? [] : {};
deepCopy(p[i], c[i]);
}
else {
c[i] = p[i];
}
}
return c;
}
使用時這樣寫:
var Doctor = deepCopy(Chinese);
現(xiàn)在,給父對象加一個屬性润文,值為數(shù)組姐呐。然后,在子對象上修改這個屬性:
Chinese.birthPlaces = ['北京','上海','廣州'];
Doctor.birthPlaces.push('深圳');
這時转唉,父對象就不會受到影響了皮钠。
alert(Doctor.birthPlaces); //北京, 上海, 廣州, 深圳
alert(Chinese.birthPlaces); //北京, 上海, 廣州
目前,jQuery庫使用的就是這種繼承方法赠法。
至于構造函數(shù)的繼承麦轰,請參考http://www.reibang.com/p/96bdc8563155