上一篇JavaScript繼承詳解(Klass)介紹了各種繼承的模式苛蒲。但究竟為何要繼承?一個(gè)很重要的目的就是為了代碼復(fù)用绿满。因此還有一種非常簡(jiǎn)單粗暴的方式臂外,直接無(wú)腦拷貝父對(duì)象的各屬性。
另一種繼承模式:通過(guò)復(fù)制屬性實(shí)現(xiàn)繼承。將對(duì)象從另一個(gè)對(duì)象中獲得需要復(fù)制功能:
function extend(parent, child) {
var i;
child = child || {};
for(i in parent) {
if(parent.hasOwnProperty(i)) {
child[i] = parent[i];
}
}
return child;
}
var p1 = {name:"Jack"};
var c1 = extend(p1);
console.log(c1.name); //Jack
上面是淺復(fù)制漏健,遍歷父對(duì)象的屬性復(fù)制給子對(duì)象嚎货,但如果屬性是數(shù)組或?qū)ο螅粫?huì)淺復(fù)制屬性:
var p2 = {
counts: [1, 2, 3],
interest: {read: true}
};
var c2 = extend(p2);
console.log(p2.interest === c2.interest); //true
c2.counts.push(4);
console.log(p2.counts.toString()); //1,2,3,4
c2.interest.play = true;
console.log(p2.interest.play); //true
JS里淺復(fù)制的概念和傳統(tǒng)OO語(yǔ)言里對(duì)指針的淺復(fù)制一樣漾肮,并無(wú)二致厂抖。上例中在子類(lèi)對(duì)象上,對(duì)數(shù)字或?qū)ο髮傩赃M(jìn)行操作會(huì)影響到父類(lèi)對(duì)象克懊。通常這不是我們想要的效果忱辅,因此要改成深復(fù)制,即如果屬性是數(shù)組或?qū)ο缶蜕顝?fù)制該屬性:
function extend(parent, child) {
var i;
child = child || {};
for(i in parent) {
if(parent.hasOwnProperty(i)) {
if(typeof parent[i] === "object") {
child[i] = (Array.isArray(parent[i])) ? [] : {};
extend(parent[i], child[i]);
} else {
child[i] = parent[i];
}
}
}
return child;
}
var p3 = {
counts: [1, 2, 3],
interest: {read: true}
};
var c3 = extend(p3);
console.log(p3.interest === c3.interest); //false
c3.counts.push(4);
console.log(c3.counts.toString()); //1,2,3,4
console.log(p3.counts.toString()); //1,2,3
c3.interest.play = true;
console.log(c3.interest.play); //true
console.log(p3.interest.play); //undefined
這種模式被廣泛使用谭溉,F(xiàn)irebug的extend方法是淺復(fù)制墙懂,jQuery的extend是深復(fù)制。當(dāng)然不論是淺復(fù)制還是深復(fù)制扮念,并沒(méi)有涉及原型损搬,僅復(fù)制它們自身的屬性。
Mix-in
這種復(fù)制屬性實(shí)現(xiàn)繼承的思想可以進(jìn)一步擴(kuò)展成Mix-in混入模式柜与。并不完整地復(fù)制一個(gè)對(duì)象巧勤,而是從多個(gè)對(duì)象中復(fù)制出屬性,將其組合成一個(gè)新對(duì)象
function mixin() {
var i, prop, child = {};
for(i=0; i<arguments.length; i+=1) {
for(prop in arguments[i]) {
if(arguments[i].hasOwnProperty(prop)) {
child[prop] = arguments[i][prop];
}
}
}
return child;
}
你可以用它傳遞任意數(shù)量的對(duì)象:
var person = mixin(
{age:33, gender:'male', location:'Shanghai'},
{interest: "read travel"},
{job: "IT"}
);
console.dir(person);
//arg 33
//gender "male"
//interest "read travel"
//job "IT"
//location "Shanghai"
總結(jié)
本文結(jié)合JavaScript繼承詳解(Klass)把繼承介紹的差不多了弄匕。你能在各種庫(kù)中找到各種模式的蛛絲馬跡颅悉。當(dāng)然有時(shí)候簡(jiǎn)單的代碼復(fù)用其實(shí)沒(méi)必要用繼承,你只不過(guò)想借用別人的方法迁匠,并不希望與它們形成父子關(guān)系剩瓶,那你用call和apply即可。