<pre>簡而言之易遣,對(duì)象的擴(kuò)展就是通過類似于<strong>extend</strong>的方法,將對(duì)象的功能進(jìn)行方便的管理(刪除或者添加或者是修改)。
</pre>
我們能夠輕松想到的方法是
let extend = (destination, source) => {
let i;
for (i in source) {
destination[i] = source
}
}
首先,在IE中<code>valueOf toString</code>等方法使用<code>for in</code>循環(huán)無法被遍歷出來钙姊,那么在司徒正美的<code>mass Framework</code>中的<code>mix</code>方法是如何實(shí)現(xiàn)的呢?
function mix(receiver, supplier) {
var args = [].slice.call(arguments),
i = 1,
key, //如果最后參數(shù)是布爾埂伦,判定是否覆寫同名屬性
ride = typeof args[args.length - 1] === "boolean" ? args.pop() : true;
if (args.length === 1) { //處理$.mix(hash)的情形
receiver = !this.window ? this : {};
i = 0;
}
while ((supplier = args[i++])) { //允許合并多個(gè)對(duì)象
for (key in supplier) { //允許對(duì)象糅雜,用戶保證都是對(duì)象
if (hasOwn.call(supplier, key) && (ride || !(key in receiver))) {
receiver[key] = supplier[key];
}
}
}
return receiver;
}
}
其實(shí)呢思恐,這種類似于對(duì)象合并的方法沾谜,在es6中已經(jīng)有了相應(yīng)的原生方法即Object.assign(target, source1, source2)
,并且在各大瀏覽器已經(jīng)得到廣泛的支持胀莹。
但是基跑,不得不注意的是這個(gè)方法只是對(duì)象的淺拷貝,即獲取的是源對(duì)象的引用描焰,而且如果存在同名屬性媳否,后面的屬性會(huì)覆蓋前面的屬性(這一點(diǎn)在司徒的mix
方法中已經(jīng)做過考慮),那么我們需要一個(gè)方法來進(jìn)行深拷貝的對(duì)象合并荆秦。
于是我做了如下的嘗試:
function assign (target, source, boolean) {
let args = [].slice.call(arguments),
i = 1,
key, //如果最后參數(shù)是布爾篱竭,判定是否覆寫同名屬性
ride = typeof args[args.length - 1] === "boolean" ? args.pop() : true;
let getSameObj = obj => {
if (typeof obj !== "object") {
return obj;
}
let s = {};
if (obj.constructor != Array) {
s = {};
Object.getOwnPropertyNames(obj).forEach(item => {
s[item] = getSameObj(obj[item])
}) //遍歷包括不可枚舉的屬性
}
return s;
}
if (args.length <= 1) {
return target || {}
}
while ((source = getSameObj(args[i++]))) { //允許合并多個(gè)對(duì)象,并使用的是深拷貝
Object.getOwnPropertyNames(source).forEach(key => {
if (source.hasOwnProperty(key) && (ride || !(key in target))) {
target[key] = source[key];
}
})
}
return target
}