1. 程式人生 > >深入學習jquery原始碼之extend()

深入學習jquery原始碼之extend()

jQuery.extend([deep], target, object1, [objectN])

概述:

用一個或多個其他物件來擴充套件一個物件,返回被擴充套件的物件。

如果不指定target,則給jQuery名稱空間本身進行擴充套件。這有助於外掛作者為jQuery增加新方法。 如果第一個引數設定為true,則jQuery返回一個深層次的副本,遞迴地複製找到的任何物件。否則的話,副本會與原物件共享結構。 未定義的屬性將不會被複制,然而從物件的原型繼承的屬性將會被複制。

引數:

target,[object1],[objectN]  Object,Object,Object

target:一個物件,如果附加的物件被傳遞給這個方法將那麼它將接收新的屬性,如果它是唯一的引數將擴充套件jQuery的名稱空間。

object1:待合併到第一個物件的物件。

objectN:待合併到第一個物件的物件。

 

[deep],target,object1,[objectN] Object,Object,Object,Object

deep:如果設為true,則遞迴合併。

target:待修改物件。

object1:待合併到第一個物件的物件。

objectN:待合併到第一個物件的物件。

 

使用:

合併 settings 和 options,修改並返回 settings。

var settings = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
jQuery.extend(settings, options);
settings == { validate: true, limit: 5, name: "bar" }

合併 defaults 和 options, 不修改 defaults。

var empty = {};
var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
var settings = jQuery.extend(empty, defaults, options);
settings == { validate: true, limit: 5, name: "bar" }
empty == { validate: true, limit: 5, name: "bar" }

$.extend(item)

該方法是將item合併到Jquery的全域性物件中去,相當於為Jquery全域性物件添加了一個靜態方法

  $.extend({SayHello:function(value){alert(“hello “+value);}});

  這樣寫過之後,就可以直接呼叫SayHello方法:

  $.SayHello(“Olive”);

extend(result,item1,item2…..)

這裡這個方法主要用來合併,將所有的引數項都合併result中,並返回result,但是這樣就會破壞result的結構。

(function ($) { /*** 統一設定datagrid 的一些預設引數*/
    $.extend($.fn.datagrid.defaults,
        {
            rownumbers: true,
            fit: true,
            pagination: true,
            striped: true,
            method: "post",
            pageSize: 20,
            pageList: [20, 50, 100]
        });
})(jQuery);
$.extend($.fn.datagrid.methods, {    
    addEditor : function(jq, param) {    
        if (param instanceof Array) {    
            $.each(param, function(index, item) {    
                var e = $(jq).datagrid('getColumnOption', item.field);    
                e.editor = item.editor;    
            });    
        } else {    
          //獲取datagrid欄位的屬性  
            var e = $(jq).datagrid('getColumnOption', param.field);    
          //給編輯器賦值  
            e.editor = param.editor;    
        }    
    },    
    removeEditor : function(jq, param) {    
        if (param instanceof Array) {    
            $.each(param, function(index, item) {    
                var e = $(jq).datagrid('getColumnOption', item);    
                e.editor = {};    
            });    
        } else {    
            var e = $(jq).datagrid('getColumnOption', param);    
            e.editor = {};    
        }    
    }    
}); 
		    $.get(form_url + key, function (data) {
		        $submit_form.form("load", data.data.installCheckVo	);
		        $("#dglist2").datagrid({ data: data.data.deviceUserList });
		        if(pagetype == "show"){
		        	debugger;
		        	$("#dglist2").datagrid('removeEditor', 'deviceName');  
		        	$("#dglist2").datagrid('removeEditor', 'deviceNumber');  
		        	$("#dglist2").datagrid('removeEditor', 'assetsNumber');         	
		        }
		    });

extend({},item1,item2,……)

用這個方法,可以將所得的結果全部合併在{}中,並返回,而且還不會破壞原有的項的結構。

Var item={name:”olive”,age:23};

Var item1={name:”Momo”,sex:”gril”};

Var result=$.extend({},item,item1);

結果:

Result={name:”Momo”,age:23,sex:”gril”};

以上的結果表明extend方法將所有的項都合併到了{}中,但是其中item1中的name:“Momo” 將item中的name:“olive”給覆蓋了

var defaults = {};
this.settings = $.extend({},defaults,options);

var defaults = {
	    		fieldCode: "gfyId",
	            url: "../../Security/selector/user/PublicServiceUserList.html?s=" + Math.random(),
	            multi: false,
	            code: "gfyId,gfyIdName",
	            keyRespField: "gfyId,id",
	            dictCode: "publicserviceName",
	            area: ['70%','70%']
	    };
		this.settings = $.extend({},defaults,options);

extend(bool,{},item1,item2….)

Extend方法還有帶bool型引數的過載。bool型引數為true表示深拷貝,為false時表示淺拷貝。具體可以通過一下示例來說明:

示例:

var item={name:“olive”,age:23,address{provice:”河南”,city:”鄭州”}};

var item1={sex:”girl”,address{city:”北京”}};

var result=$.extend(true,item,item1);

var result1=$.extend(false,item,item1);

結果:

Result={name:“olive”,age:23,sex:”gril”,address:{provice:”河南”,city:”北京”}};

Result1={name:“olive”,age:23,sex:”gril”,address:{ city:”北京”}};

說明:

以上結果說明,當引數為ture時,即為深拷貝,當子項item1中的子項有與item中的子項相同屬性的值不一樣時,item1中子項的值會將item子項中的值給覆蓋,當子項item1的屬性跟item中的屬性不同時,會與item進行合併。

當引數為false時,子項item1中的子項中與item中的子項屬性相同時,item1中子項的屬性值會將item中的值給完全覆蓋。

 options: $.extend(true, {}, $.fn.gridsub.defaults, options)

使用extend還可以建立物件

				var option = $.extend({elem:  "#" + _self.container, 
									   url : _self.url, 
									   cols: _self.title,
									   method: RequestMethod.METHOD_POST,
									   id : _self.tableId,							
									   even: true,
									   page: true,									//是否顯示分頁
									   pageNum: 1,
									   limit: _self.pageSize, 						//每頁預設顯示的數量
									   limits:[5,10,15,20,30],
									   done:function(res, curr, count){
										   debugger;
										   if(_self.afterDone && $.isFunction(_self.afterDone)){
						           				_self.afterDone(res, curr, count);
						           			}
									   }}, _self.layOption);
				//展示已知資料
				layui.table.render(option);
				

 

 

 

jQuery的原始碼實現

    jQuery.extend = jQuery.fn.extend = function () {
        var src, copyIsArray, copy, name, options, clone,
            target = arguments[0] || {},
            i = 1,
            length = arguments.length,
            deep = false;

        // Handle a deep copy situation
        if (typeof target === "boolean") {
            deep = target;

            // skip the boolean and the target
            target = arguments[i] || {};
            i++;
        }

        // 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 (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 (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
                    if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
                        if (copyIsArray) {
                            copyIsArray = false;
                            clone = src && jQuery.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;
    };