jq中extend函式中的deep引數

2021-07-26 15:50:25 字數 3926 閱讀 1355

昨天在研究繼續研究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...