jquery和zepto的擴展方法extend


 

 

jquery和zepto的擴展方法extend

總結下jQuery(3.1.1)和zepto(1.1.6)到底是如何來開放接口,使之可以進行擴展,兩者都會有類型判斷,本文使用簡單的類型判斷,暫不考慮兼容。

類型判斷

var class2type = {},toString = class2type.toString,$={}; //判斷類型 function type(obj) { return obj == null ? String(obj) : class2type[toString.call(obj)] || "object" } //對象 function isObject(obj) { return type(obj) == "object" } //字面量對象 function isPlainObject(obj) { return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype } function isArray(arr){ return Array.isArray(arr) || arr instanceof Array }

zepto.extend

3

zepto中的擴展,我們可以看到,首先是定義了一個extend函數,這個在內部使用的函數有三個參數target,source,deep。target是將被擴展的對象,source是擴展的對象,deep代表是否深度擴展。那么就直接看第三個參數了。
我們可以看到,在extend函數中,即使使用了深度擴展,也會通過遞歸函數來重新擴展,最后都會是targte[key]=source[key],而區別是:

//test1 var test1 = {  name:"a",  item:{  name:"b",  nickname:"c" } }; //簡單擴展 extend(test1,{name:"a",item:{name:"b",item:{name:"c"}}}); console.log(test1);

4
可以看到,在沒有使用deep時,會直接擴展對象的第一層屬性,並直接覆蓋。但如果使用了deep:

//深度擴展 extend(test1,{name:"a",item:{name:"b",item:{name:"c"}}},true); console.log(test1);

5
現在擴展對象時就不會修改原對象中不對應的值。
然后是$.extend,這個是可以在外部使用的擴展函數,直接在$對象上定義的,zepto的插件擴展可以不需要通過$.extend擴展到zepto對象里,因為zepto的dom.__proto__ = $.fn,zepto.Z.prototype = $.fn,且返回的是$。所以我們可以看見在zepto其他的模塊里,給zepto添加動態方法時,是這樣直接擴展的:
6
回到$.extend函數,這里在內部使用arguments,所以該函數是不限參數的,如果想深度擴展,只需要把首個參數設為true。首先是簡單擴展的:

var test2 = $.extend(test1,{name:"a",item:{name:"b",item:{name:"c"}}},{name:"d"}); console.log(test2);

7

深度擴展:

var test2 = $.extend(true,test1,{name:"a",item:{name:"b",item:{name:"c"}}},{name:"d",item:{name:"e"}}); console.log(test2);

8

jQuery.extend 和jQuery.fn.extend

9

看jQuery的擴展,得益jQuery返回的是一個真實的jQuery對象,其內部使用jQuery.fn來划分了作用域,所以擴展上,因為this的不同,如果擴展jQuery對象,extend是直接擴展在jQuery本身上的,而fn.extend是擴展在jQuery.prototype原型對象上。而實現函數其實是一樣的。

在jQuery中使用擴展時,如果除了第一個參數的boolean值之外,參數的長度等於內部定義的長度,都會擴展到jQuery自身,而zepto想要擴展到自身,可以將zepto對象設為第一個參數

jQuery在循環里加入了if ((options = arguments[i]) != null)所以當給null或undefined賦值時,直接返回擴展對象,而且因為上面的arguments長度判斷,不會擴展到jQuery上去。而zepto則直接報錯target[key] = source[key]
zepto:
12
13
jQuery:
14
15

jQuery中的extend語法與上面的zepto相同,在zepto里,最后對如果沒有proto做了兼容:
11

在jQuery中$.extend()與$.fn.extend()是不同也相同的,在上面的源碼里我們也看到了,jQuery.extend = jQuery.fn.extend,只是因為兩個函數的this值指向不同,所以能夠使用的場景也不同,可以大致分為動態和靜態。在使用jQuery的過程中,jQuery的最外層匿名函數里會執行,返回一個jQuery對象,並與$一起綁在window上,所以引入文件之后已經存在,而動態指的是jQuery.fn.init(selector,context);所以需要先初始化再使用相應方法。

小結

這里將一些瑣碎的知識點歸納了一下,事實上,zepto的擴展與jQuery的擴展在使用的方法上看起來一樣,但jQuery更細。了解兩者的區別能夠在需要兼容zepto和jQuery時不會犯未知錯誤,也對擴展插件有更好的幫助。本文使用demo(有源碼注釋):jQuery與zepto的extend

長路漫漫,與君共勉
如果您看完本篇文章感覺不錯,請點擊一下右下角的 推薦來支持一下博主,謝謝!
 
分類:  javaScript


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM