標籤:sar 深拷貝 isp http situation 重要 return put 引用
jquery的extend方法現項目中經常使用,現在瞭解一下它的實現。
說起extend就要先瞭解一個jQuery的$.extend和$.fn.extend作用及區別
jQuery為開發外掛程式提拱了兩個方法,分別是:
1. jQuery.fn.extend();
2. jQuery.extend();
雖然 javascript沒有明確的類的概念,但是可以構建類似類的定義。
jQuery便是一個封裝得非常好的類,比如,$("#btn1") 會產生一個 jQuery類的執行個體,理解這一點很重要。
(1). jQuery.extend(object);
它是為jQuery類添加類方法,可以理解為添加靜態方法。如:
a.jQuery.extend({
min: function(a, b) { return a < b ? a : b; },
max: function(a, b) { return a > b ? a : b; }
});
jQuery.min(2,3); // 2
jQuery.max(4,5); // 5
b. jQuery.extend(target, object1, [objectN])用一個或多個其他對象來擴充一個對象,返回被擴充的對象。
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" }
(2). jQuery.fn.extend(object);
$.fn是什麼?
$.fn是指jQuery的命名空間,fn上的成員(方法function及屬性property),會對jQuery執行個體每一個有效。
查看jQuery代碼,就不難發現。
jQuery.fn = jQuery.prototype = {
init: function( selector, context ) {//....
};
原來 jQuery.fn = jQuery.prototype.
所以,它是對jQuery.prototype進得擴充,就是為jQuery類添加“成員函數”。jQuery類的執行個體可以使用這個“成員函數”。
比如我們要開發一個外掛程式,做一個特殊的編輯框,當它被點擊時,便alert 當前編輯框裡的內容。可以這麼做:
$.fn.extend({
doAlertWhileClick:function() {
$(this).click(function(){
alert($(this).val());
});
}
});
$("#input1").doAlertWhileClick(); // 頁面上為:
$("#input1") 為一個jQuery執行個體,當它調用成員方法 doAlertWhileClick後,便實現了擴充,每次被點擊時它會先彈出目前編輯裡的內容。
jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[ 0 ] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { //判斷第一個參數是否為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
////解決循環參考的問題,比如:var a ={};$.extend( a , { name:a } ),如果不做這個處理,將會得到一個死迴圈的對象(a{name:{name:{name:{...}}}}),加了這個,就擴充不上,a還是{}
if ( target === copy ) { continue; } // Recurse if we‘re merging plain objects or arrays
// //如果是深拷貝,並且擴充項物件的name屬性值存在,並且擴充項物件是一個對象自變數(或者是一個數組),就進入if語句
if ( deep && copy && ( jQuery.isPlainObject( copy ) || ( copyIsArray = jQuery.isArray( copy ) ) ) ) { if ( copyIsArray ) {// //如果擴充項物件的name屬性值是數組,進入if語句 copyIsArray = false; clone = src && jQuery.isArray( src ) ? src : []; ////如果目標對象的name屬性值是一個數組,就取這個數組,如果不是,就取[] } else { clone = src && jQuery.isPlainObject( src ) ? src : {};////如果目標對象的name屬性值是一個對象自變數,就取這個對象自變數,如果不是,就取{} } // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy );
//遞迴調用extend,深拷貝擴充項物件的name屬性值(對象或者數組)到clone。
//遞迴結束後,返回clone,賦值給目標元素的name屬性
//這就把擴充項物件的所有屬性都擴充到目標對象中了。
// Don‘t bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target;};
引:http://www.cnblogs.com/Dlonghow/p/4142034.html
http://www.cnblogs.com/chaojidan/p/4145168.html
jquery源碼學習之extend