jquery1.4 jquery1.4下載jquery
這裏使用了 jQuery1.4,爲何使用 1.4 由於 1.4 不少特性沒有添加分析起來相對容易。api
extend 能夠說是 jQuery 用的最多的函數之一了,除了核心的幾個函數以外其餘的幾乎所有用 extend 進行原型或者靜態函數的擴展。下面來看看 extend 若是完成這樣的工做的吧數組
jQuery.extend = jQuery.fn.extend = function() { // copy reference to target object var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy; // Handle a deep copy situation // 深度拷貝 if ( typeof target === "boolean" ) { deep = target; // 修正深度拷貝 target = arguments[1] || {}; // 修正目標 // skip the boolean and the target // 若是是深度拷貝 修正循環(跳過第一個參數(0)和目標(1)) i = 2; } // Handle case when target is a string or something (possible in deep copy) // 確保目標元素是對象且不是函數,但能夠是函數對象(new 函數) if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; } // extend jQuery itself if only one argument is passed // 當擴展的對象只有一個的時候,就視爲擴展 jQuery if ( length === i ) { target = this; // 修正 this 爲jQuery --i; } // 遍歷參數 for ( ; i < length; i++ ) { // Only deal with non-null/undefined values // 遍歷不是 null 的值(對象) 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 object literal values or arrays // 深拷貝,且 copy 是對象或者數組 /** * deep => true * copy == true * copy => 必須是絕對對象 或 copy 是一個數組 * */ if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) { /** * 若是目標元素和要拷貝的元素有相同的 key 而且也是對象或者數組那麼就返回目標對象的 key * 不然建立一個對應的類型用於保存數據 */ var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src : jQuery.isArray(copy) ? [] : {}; // 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; };
下面我列出一下 extend 的一些用法 手冊描述函數
一、這種是最基本的用法oop
var t = $.extend({a:"123"}, {b:'456'}); console.log(t); //Object {a: "123", b: "456"}
二、深度拷貝this
var o1 = { txt: "123", a: { 'a_text': 'a_text' } }; var o2 = { txt1: '456', b: { 'b_text': '123' } }; debugger; var t = $.extend(false,o1,o2); t['b']['b_text'] = '改變成文本'; console.log(t); console.log(o1,o2); // -----------------------------深度克隆------------------------------------ var o1 = { txt: "123", a: { 'a_text': 'a_text' } }; var o2 = { txt1: '456', b: { 'b_text': '123' } }; debugger; var t = $.extend(true,o1,o2); t['b']['b_text'] = '改變成文本'; console.log(t); console.log(o1,o2);
咱們看當深度克隆參數爲 false 的時候,擴展出來的對象 key 爲 b 的和元素對象 key 爲 b 的是指向的同一個引用。因此當我改變了克隆回來的對象 t 值 'b_text' 的時候原始對象也跟着變了。spa
再來看看深度克隆的狀況,當我改變了克隆回來的對象 t 值 'b_text' 的時候原始對象沒有跟着變了。.net
三、接下來看看爲 jQuery 擴展插件的狀況插件
jQuery.extend = jQuery.fn.extend = function(){};
他這裏爲 jQuery 靜態函數 和 原型都添加了 extend 函數, 因此咱們要編寫插件只須要給原型添加一個擴展函數就能夠啦。debug
$.fn.extend({tudou:function(){alert('hello tudou')}});
看一下他這裏怎麼實現的,其實原理很簡單。
// 當擴展的對象只有一個的時候,就視爲擴展 jQuery if ( length === i ) { target = this; // 修正 this 爲jQuery --i; }
當你只傳遞一個對象的時候他會把 擴展的目標指向當前 this,因此能很方便的進行插件編寫。
好啦結束了。。。