jQuery 的 API 手冊中,extend 方法掛載在 jQuery 和 jQuery.fn 兩個不一樣的對象上,但在 jQuery 內部代碼實現的是相同的,只是功能各不相同。css
先看看官方給出的解釋:json
jQuery.extend Merge the contents of two or more objects together into the first object. 把兩個或者多個對象合併到第一個對象當中;數組
jQuery.fn.extend Merge the contents of an object onto the jQuery prototype to provide new jQuery instance methods. 把對象掛載到 jQuery 的 prototype 上以擴展一個新的 jQuery 實例方法 。ide
雖然官方對 jQuery.extend 的擴展方法功能隻字未提,可是它也一樣具備擴展 jQuery 類方法 的功能。函數
首先,我先來介紹一下 extend 函數在 合併對象 方面的用法。工具
jQuery.extend(target [, object1] [, objectN])
合併 object1 ... objectN 到 target 對象,若是隻有一個參數,則該 target 對象會被合併到 jQuery 對象中。this
var obj1 = { name: 'Tom', age: 21 } var obj2 = { name: 'Jerry', sex: 'boy' } $.extend(obj1, obj2); // {name: "Jerry", age: 21, sex: "boy"} obj1 // {name: "Jerry", age: 21, sex: "boy"} obj2 // {name: "Jerry", sex: "boy"}
上述代碼展現的是將 obj2 對象合併到 obj1 對象中,這種方法會 改變 obj1 對象的結構。若是你 不想改變 合併目標對象的結構,你能夠這麼作。prototype
var obj1 = { name: 'Tom', age: 21 } var obj2 = { name: 'Jerry', sex: 'boy' } $.extend({}, obj1, obj2); // { name: "Jerry", age: 21, sex: "boy" } obj1 // { name: "Tom", age: 21 } obj2 // { name: "Jerry", sex: "boy" }
jQuery.extend([deep], target, object1 [, objectN])
和上面的講述的不一樣的是,該方法多了一個類型爲 boolean 的 [deep] 傳參,當其爲 true 時,將 object1 , objectN 深度複製 後合併到 target 中。code
首先,咱們理解一下什麼叫作 深度複製 。看看其和 淺度複製 有什麼區別。對象
var obj1 = { name: "John", location: { city: "Boston", county: "USA" } } var obj2 = { last: "Resig", location: { state: "MA", county: "China" } } $.extend(false, {}, obj1, obj2); // { name: "John", last: "Resig", location: { state: "MA", county: "China" }} $.extend(true, {}, obj1, obj2); // { name: "John", last: "Resig", location: { city: "Boston", state: "MA", county: "China" }}
因而可知,執行 深度複製 會遞歸遍歷每一個對象中含有複雜對象(如:數組、函數、json對象等)的屬性值進行復制,並且 淺度複製 便不會這麼作。
上述的 extend 方法中的 target 參數是能夠省略的。若是省略了,則該方法就只能傳入一個 object 參數,該方法功能是將該 object 合併到調用 extend 方法的對象中。
咱們一般會使用這種方式來對 jQuer進行一些方法上的擴展。
jQurey 提供了兩種方法擴張方式,分別爲jQuery.fn.extend(object)
和jQuery.extend(object)
.
想要搞清楚兩種擴展方式之間的區別的話,先要了解什麼是jQuery.fn
.
本猿參考了 jQuery 的源碼,發現其中玄機:
jQuery.fn = jQuery.prototype = { init: function(selector, context) { // ... }; }
jQuery.fn = jQuery.prototype
這句代碼明確指出jQuery.fn
指代的就是 jQuery 的原型。
其次,咱們要引入兩個概念 類方法 和 實例方法 。
類方法 是直接可使用類引用,不須要實例化就可使用的方法。通常在項目中 類方法 都是被設置爲工具類使用;
實例方法 必須先建立實例,而後才能經過實例調用該 實例方法 。
jQuery
能夠看作是這個封裝得很是好的類,而咱們可使用jQuery選擇器
來建立 jQuery 的實例。好比:使 id 選擇器$('#btn')
來建立一個實例。
jQuery.extend(object)
至關於對 類方法 的擴展。
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
jQuery.fn.extend(object)
是對jQuery.prototype
上的擴展。
jQuery.fn.extend = jQuery.prototype.extend
這種方式至關對 實例方法 的擴展。
舉個栗子:
開發一個簡單的小功能,使用該方法可使選定元素內的文字變紅。
$.fn.extend({ setRed: function() { $(this).css("color", "red"); } }); $('.tip').setRed();
$(".tip")
建立了一個jQuery實例
,經過它能夠調用成員方法setRed
.
上述代碼能夠實現預想的擴展,但最好返回this
以知足 jQuery 鏈式操做 的須要。
改良以後,代碼以下:
$.fn.extend({ red: function() { return $(this).css("color", "red"); } });