$.extend
用於合併對象,可選擇是否深複製。使用時,第一個參數爲合併後的對象。若是要進行深拷貝,則參數1爲true
,參數2爲要合併的目標對象。儘管jQuery官方文檔明確指出第一個參數是false
的調用狀況並不支持,可是這個版本的源碼中,判斷第一個參數的類型雖有限定是boolean
類型,但卻未對其值真假加以限定。因此第一個參數是false
也是可行的。jquery
$.fn.extend({})
用於拓展jq原型對象,使用只能傳入一個對象,多用於jq插件定義。api
jQuery.extend( target [, object1 ] [, objectN ] ) Query.extend( [deep ], target, object1 [, objectN ] ) jQuery.fn.extend( object )
jQuery.extend
和jQuery.fn.extend
指向同一個函數,在函數內部,對調用狀況進行區分。首先判斷第一個參數的類型,肯定是否顯式指定深複製。使用target
保存合併對象的引用,若是target
不是對象的,要指向空對象。數組
接着判斷參數的個數,區別jQuery.extend
或jQuery.fn.extend
的調用。而後使用for
循環,從第二個參數開始遍歷,進行拷貝;拷貝時使用src
保存target上的屬性,copy
保存被合併對象上的屬性。使用for...in
循環遍歷屬性名進行拷貝,拷貝時忽略對target
自身引用,copy
爲空時也會被忽略,若是根據是否須要深拷貝來決定是否對object
和array
遞歸深拷貝。若是是淺拷貝,直接保存值或引用。函數
值得一提的是,遍歷被合併對象時使用的是for...in
循環,因此傳入string
和array
類型的參數也會被遍歷,在合併後對象中的屬性名爲索引。因爲遍歷參數是從target後的第一個參數開始,因此先傳入的對象會被後傳入對象的同名屬性覆蓋。oop
jQuery.extend = jQuery.fn.extend = function() { // target是對象或true,從第二個參數開始遍歷 var options, name, src, copy, copyIsArray, clone, target = arguments[ 0 ] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation // 第一個參數若是是boolean,代表顯示指定是否深複製 if ( typeof target === "boolean" ) { deep = target; // Skip the boolean and the target // 將target指向第一個參數,從第三個參數開始合併 target = arguments[ i ] || {}; i++; } // Handle case when target is a string or something (possible in deep copy) // 不是對象或函數,將target設置默認空 if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { target = {}; } // Extend jQuery itself if only one argument is passed // 只有一個參數,即$.fn.extend({}),target指向jq原型 if ( i === length ) { target = this; i--; } // 先傳入的對象會被後傳入對象的同名屬性覆蓋 for ( ; i < length; i++ ) { // Only deal with non-null/undefined values // 保存當前的非空對象。 if ( ( options = arguments[ i ] ) != null ) { // Extend the base object // 遍歷,for...in會遍歷數組或字符串 // src爲target屬性值,copy爲闖入對象的屬性值 for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop // 自身的屬性指向自身,這種狀況避免無限循環,跳過自身引用的複製 if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays // 深複製時,調用$.extend遞歸調用。 // 複製時保存屬性的原始類型,只有對象或數組才必要進行深複製 if ( deep && copy && ( jQuery.isPlainObject( copy ) || ( copyIsArray = Array.isArray( copy ) ) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && Array.isArray( src ) ? src : []; } else { clone = src && jQuery.isPlainObject( src ) ? src : {}; } // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values // 淺複製,值非空直接複製或保存引用 } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; };