依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));
以上~~希望對您有所幫助^^
留言列表