依Jquery的1.3.2版來看, 內部設定時
函數(extend)被使用了18次, 關鍵字 .extend(
所以這篇文章就要來研究一下這函數在做什麼
extend的定義:Jquery對外開放的函數, 用來擴充及複寫原有函數內容, 或者合併二個物件內容。
一般在事先定義類別函數可以使用以下宣告語法
function obj_base(){
this.extend = function(obj){};
}
而物件被產生後, 要修改函數內容, 可以使用以下語法
var ob = new obj_base();
ob.extend = function(obj){};
或者以下語法也可以達到相同目的,
而Jquery的extend函數也是使用這個的方式來達到擴充及複寫
var ob = new obj_base();
ob['extend'] = function(obj){};
使用簡單的程式碼來表達,如下
/*產生物件*/
var ob = new obj_base();
/*擴充函數*/
ob.extend({
A:function(){alert('IS_A');}
B:function(){alert('IS_B');}
C:function(){alert('IS_C');}
});
/*執行擴充函數*/
ob.B();
/*類別內容*/
function obj_base(){
var me = this;
this.extend = function(obj){
for(var key in obj){
me[key]=obj[key];
}
}
}
回頭來看jQuery.extend內容
jQuery.extend = jQuery.fn.extend = function() {
// copy reference to target object
var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
// Handle a deep copy situation
if ( typeof target === "boolean" ) {
deep = target;
target = arguments[1] || {};
// skip the boolean and the target
i = 2;
}
// Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && !jQuery.isFunction(target) )
target = {};
// extend jQuery itself if only one argument is passed
if ( length == i ) {
target = this;
--i;
}
for ( ; i < length; i++ )
// Only deal with non-null/undefined values
if ( (options = arguments[ i ]) != null )
// Extend the base object
for ( var name in options ) {
var src = target[ name ], copy = options[ name ];
// Prevent never-ending loop
if ( target === copy )
continue;
// Recurse if we're merging object values
if ( deep && copy && typeof copy === "object" && !copy.nodeType )
target[ name ] = jQuery.extend( deep,
// Never move original objects, clone them
src || ( copy.length != null ? [ ] : { } )
, copy );
// Don't bring in undefined values
else if ( copy !== undefined )
target[ name ] = copy;
}
// Return the modified object
return target;
};
它提供了三種的參數內容
jQuery.extend({key:value}):擴充及修改jQuery本身的函數, 在jQuery檔內很常見。
jQuery.extend({
is_new_fn:function(){
alert('use new function');
}
});
jQuery.extend(obj, {key:value}):擴充及修改傳入物件的函數, 在修改插件時會比較常用。
以jQuery ui datepicker為例, 可以透過以下方式修改星期顯示的數值
jQuery.extend(jQuery.datepicker._defaults,{
dayNames: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
dayNamesShort: ['日', '一', '二', '三', '四', '五', '六'],
dayNamesMin: ['日', '一', '二', '三', '四', '五', '六']
});
以上二個參數方式, 主要功能為擴充及修改
而造成jQuery.extend函數複雜的原兇是以下參數例子
jQuery.extend(bool, obj, obj1, obj2...,objN):執行結果是將obj1, obj2...,objN全部的內容複製到obj上, 而bool是在決定是否遞迴。
透過以下範例來說明, 建立A, B 二個物件, 讓 C 透過 extend 來取得 A, B 物件內容, 而 D 直接等於 A, 在執行過程中去修改 A.ax 內容。
最後輸出結果來看, A物件的修改會影響D物件, 而C物件卻是獨立個體, 同時還包含了B物件的方法。。
var A = {
ax:function(n){return n+'is_a_fn';}
};
var B = {
bx:function(n){return (n+'is_b_fn');}
};
var C = extend(true, {}, A, B);
var D = A;
var S ='';
S += '\n'+A.ax('A:');
S += '\n'+C.ax('C:');
S += '\n'+D.ax('D:');
A.ax = function(n){return (n+'is_new_a_fn');}
S += '\n\n修改A.ax後';
S += '\n'+A.ax('A:');
S += '\n'+C.ax('C:');
S += '\n'+D.ax('D:');
S += '\n\nC物件具有B物件的方法';
S += '\n'+C.bx('C:');
alert(S);
function extend() {
var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
deep = target;
target = arguments[1] || {};
i = 2;
for ( ; i < length; i++ )
if ( (options = arguments[ i ]) != null )
for ( var name in options ) {
var src = target[ name ], copy = options[ name ];
if ( target === copy )
continue;
if ( copy !== undefined )
target[ name ] = copy;
}
return target;
};
jQuery檔內有一段code如下, 透過上面的說明, 應該就可以理解它到底做了什麼好事。
s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
以上~~希望對您有所幫助^^
留言列表