昨天在研究繼續研究js外掛程式的時候注意到了extend這個函式,然後就用幾個示例去加深對它的印象,不過在過程中對於deep這個引數產生了疑惑。當jq1.1.4版本後extend這個函式增加了乙個引數deep,用來進行選擇是否深拷貝,深淺拷貝這裡我就不說了,這裡直接用例子來看一下
1.我們可以發現當我們去改變a中的age值的時候,b中改變
var a = };
var b = }
extend(a, b);
a.tom.age = 25;
console.log(a.tom.age); //25
console.log(b.tom.age);//25
2.我們可以發現當我們去改變a中的age值的時候,b中沒有改變
var a = };
var b = }
extend(true,a, b);
a.tom.age = 25;
console.log(a.tom.age); //25
console.log(b.tom.age);//14
3.我們可以發現當我們去改變a中的age值的時候,b中沒有改變
var a = };
var b = }
extend(false,a, b);
a.tom.age = 25;
console.log(a.tom.age); //25
console.log(b.tom.age);//14
我們可以發現3個例子的區別就是第乙個引數deep是否存在和為true和false,而且第乙個例子是淺拷貝,第二個和第三個都是深拷貝
這裡可以有2個結論:
1.這個函式預設就是淺拷貝
2.傳true和false都是深拷貝
一開始對於第2個結論很不理解,講道理true為深拷貝,那麼false肯定為淺拷貝呀,為什麼都一樣呢?在網上查了很多資料,發現還是不明白,後來去官網查了一下知道(證明以後我們查東西還是去官網比較靠譜,網上很多部落格都是斷章取義),第乙個引數不能為false。
(可以去看中文的文件,也可以用chrome瀏覽器翻譯)
warning
: passing
false
for the first argument is not supported.
原來不能傳false,之所以這樣是我們一直都是慣性思維,理解true為深,那麼false肯定為淺咯~ -。-(慣性思維害死人,我還一直糾結為什麼會這樣)
其實到這裡我們都是知其然,不知其所以然,在糾結這個問題的過程中,我查了原始碼,終於知道其所以然了。
target = arguments [ 0 ] | |
//就是這一句話~(大家可以定位到這句話),它是把這個函式的第乙個引數傳遞給target,最重要的是這裡用了乙個 | | 或,如果當我第乙個是假的話
就直接賦值乙個空物件給target,這樣就可以理解,為什麼我們可以傳true不能傳false了,當我們傳true的時候為真,它就直接把true給它了,當我傳false的時候為假,它就會
把乙個空物件給target。
因為上面這個條件,我們就可以解釋為什麼當進行後面那個判斷時,我傳false會進不去的原因了,就是因為typeof (target)為object!!!!!
if ( typeof (target) === "boolean" ) ;
// skip the boolean and the target
i = 2;
}然後再看乙個例子:
var empty={};
var a = };
var b = }
extend(empty,a,b);
empty.tom.age = 25;
console.log(empty.tom.age);//25
console.log(a.tom.age); //15
console.log(b.tom.age);//25
我們可以發現,當我們去淺拷貝的時候,它只是會影響到最後乙個物件的引數,這個也可以理解,因為後面的引數會覆蓋前面的,所以淺拷貝的時候,最後被合併的物件(empty)引用的是最後乙個引數物件( b )的屬性。
所以當我們對外掛程式引數進行覆蓋的時候最好用這種方式:
第乙個引數為true,第二個引數為空物件,就是為了不讓其他物件的值被覆蓋掉。
var empty={};
var a = };
var b = }
empty=extend(true,{},a,b);
empty.tom.age = 25;
console.log(empty.tom.age);//25
console.log(a.tom.age); //15
console.log(b.tom.age);//14
最後附上別人對這個函式的原始碼解析:
jquery.extend = jquery.fn.extend = function() , //被擴充套件的物件
i = 1, //設定擴充套件物件的起始值,預設從第二項開始
length = arguments.length, //傳遞引數的個數,以便下面迴圈擴充套件物件使用
deep = false; //預設淺複製
/*處理深層拷貝或淺拷貝情況
extend(boolean,src1,src2..srcn);
*/if ( typeof target === "boolean" ) ; //重新設定被擴充套件物件,為引數的第二項
i++; //重設擴充套件物件的起始值,從第三項開始}/*
被擴充套件的不是物件或函式,可能是string,number或其他;
extend("",src1,src2...srcn);
*/if ( typeof target !== "object" && !jquery.isfunction(target) ) ; //重新設定target的值為空物件}/*
當只傳入乙個物件
extend(src1);
將target設為jquery物件或者jquery.prototype,來擴充套件jquery靜態屬性方法或是例項屬性方法
$.extend(src1); //擴充套件jquery物件
$.fn.extend(src1) //擴充套件jquery.prototype
*/if ( i === length )
/*被擴充套件物件和擴充套件物件所有情況處理完畢,開始迴圈進行拷貝
對從i開始的多個引數進行遍歷
*/for ( ; i < length; i++ )
/*物件或陣列做深拷貝
deep:判斷是否要深拷貝
copy:保證copy存在
jquery.isplainobject:判斷copy是否是乙個純粹的物件,通過{} 或 new object 建立
jquery.isarray:判斷是否為陣列
*/if ( deep && copy && ( jquery.isplainobject(copy) || (copyisarray = jquery.isarray(copy)) ) ) else ; //設定clone為乙個物件
}//遞迴深度拷貝
target[ name ] = jquery.extend( deep, clone, copy );
//過濾未定義的值
} else if ( copy !== undefined ) }}
}//返回修改後的物件
return target;
};
jquery,extjs中的extend用法小結
在jquery中,extend其實在做外掛程式時還是用的比較多的,今天同時小結jquery和ext js中 的extend用法,先來看jquery中的。1 extend dest,src1,src2,src3.var start var more var extra var extended ext...
jQuery中的extend方法
jquery 中的extend方法jquery中的extend方法通過不同的引數實現了幾種不同的繼承方法 1.extend src 將src物件的屬性和方法逐一複製給jquery或jquery物件 2.extend dest,src1,src2,src3.srcn 將 src1 src2.物件的屬性...
jquery,extjs中的extend用法小結
在jquery中,extend其實在做外掛程式時還是用的比較多的,今天同時小結jquery和ext js中 的extend用法,先來看jquery中的。1 extend dest,src1,src2,src3.var start var more var extra var extended ext...