現代繼承模式可表述爲:其餘任何不須要以類的方式考慮得模式。html
現代繼承方式#1 —— 原型繼承之無類繼承模式數組
function object(o) { function F() {}; F.prototype = o; return new F(); } function Person() { this.name = 'king'; } Person.prototype.getName = function () { return this.name; }; var papa = new Person(); var kid = object(papa); console.log(kid.getName()); //king
現代繼承方式#2 —— 經過複製屬性實現繼承app
/** * 1>包括深度複製和淺複製 * 2>引深而來,引入「mix-in」(混入)模式,它並非複製一個完整的對象,而是從多個對象中複製出任意的成員 * 並將這些成員組合成一個新的對象。 */ //淺複製 function extend(parent, child) { var i; child = child || {}; for (i in parent) { if (parent.hasOwnProperty(i)) { child[i] = parent[i]; } } return child; } //深度複製 function extendDeep(parent, child) { var i, toStr = Object.prototype.toString, astr = '[object Array]'; child = child || {}; for (i in parent) { if (parent.hasOwnProperty(i)) { if (typeof parent[i] === 'object') { child[i] = (toStr.call(parent[i]) === astr) ? [] : {}; extendDeep(parent[i], child[i]); } else { child[i] = parent[i]; } } } return child; } //測試深度複製 var dad = { counts: [1, 2, 3], reads: {paper: true} }; var kid = extendDeep(dad); kid.counts.push(4); console.log(kid.counts.toString()); //1,2,3,4 console.log(dad.counts.toString()); //1,2,3
現代繼承方式#3 —— 借用方法函數
/** * 有時候,可能剛好僅僅須要現有對象其中的一個或兩個方法。在想要重用這些方法的同時,可是又確實不但願與源對象造成父-子關係。 * 也就是說,指向使用所須要的方法,而不但願繼承全部哪些永遠都不會用到的其餘方法。 * 這個時候,能夠經過借用方法模式來實現,而這是收益與call()和apply()函數方法。 * 同時,能夠綁定函數的做用域。 */ function f() { var args = [].slice.call(arguments, 1, 3); //一樣可以使用 Array.prototype.slice.call(arguments, 1, 3); //免於建立新數組了 return args; } f(1, 2, 3, 4, 5, 6); //2,3
在上一篇文章中,介紹了函數複用模式之類式繼承模式。二者全然闡述代碼複用的模式,並造成鮮明對比。建議老是爭取採用一種現代的繼承模式,除非團隊在不涉及到類的時候對此真的感到不適應。測試
須要記住——代碼重用纔是最終目的,而繼承知識實現這一目標的方法之一。this
源自:《JavaScript模式》spa