国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

ExtJS與jQuery的一點細節上的對比

2019-11-17 01:36:37
字體:
來源:轉載
供稿:網友

ExtJS與jQuery的一點細節上的對比

首先說明這不是一篇完整解讀ExtJS和jQuery所有方面差異的文章,只是針對我個人剛看了兩天的jQuery產生的一些疑問的整理。之前用過一段時間ExtJS,了解ExtJS的一些機制。現在做移動開發,又選定了jquery mobile,要寫控件,所以需要了解jquery。(不過換工作之后應該不會再用jQuery了,坑估計是短期內填不上了)

1、jQuery是個什么東西?Ext是什么東西?(此處不是指兩個框架,而是指我們在寫程序的時候,經常用到的兩個關鍵字--暫時稱之為關鍵字)

之前用的是ExtJS,Ext是個Object,通過字面量創建的,Ext.js文件里,3.3.1版:

Js代碼
  1. Ext={
  2. version:'3.3.1',
  3. versionDetail:{
  4. major:3,
  5. minor:3,
  6. patch:1
  7. }
  8. };

4.0版本,此處global == window:

Js代碼
  1. if(typeofExt==='undefined'){
  2. global.Ext={};
  3. }

既然Ext是個Object,那jQuery是不是也是個Object呢?NO,來分析下源碼,jquery.js:

Js代碼
  1. varjQuery=(function(){
  2. //DefinealocalcopyofjQuery
  3. varjQuery=function(selector,context){
  4. //ThejQueryobjectisactuallyjusttheinitconstructor'enhanced'
  5. returnnewjQuery.fn.init(selector,context,rootjQuery);
  6. },
  7. ...//此處省略900行
  8. returnjQuery;
  9. })();

此處大概明白了,jQuery是個Function,并且由于此處調用jQuery的時候,有個return,所以var v = jQuery(xxx)和var v = new jQuery(xxx)調用后,v都是同一個函數的實例。在《javaScript高級程序設計》第18章第一節有提到過這種技巧,叫做作用域安全的構造函數,不過書上提到的形式稍有差異:

Js代碼
  1. functionPerson(name,age){
  2. if(thisinstanceofPerson){
  3. this.name=name;
  4. this.age=age;
  5. }else{
  6. returnnewPerson(name,age);
  7. }
  8. }

這樣var p = Person('a',21)和var p = new Person('a',21) ,p就都是Person實例了,如果去掉if判斷和else后邊的內容,第一種調用p是undefined。

在jquery.js最后,把變量jQuery賦值給了$,后續可以通過$這種簡寫使用jQuery,算是一個簡寫的別名吧:

Js代碼
  1. window.jQuery=window.$=jQuery;

此處先挖個坑,構造函數中(如此處的Person)的this到底怎么理解?

2、jQuery和Ext在這兩個關鍵字都怎么使用的,有何異同?

2.1、Ext是個對象,是一個命名空間,跟java里頭的package類似,使用Ext下邊的方法、Function/類的時候,就像使用一個對象的屬性一樣,如工具方法Ext.apply、Ext.applyIf可以直接調用,構造函數Ext.json.DataStore,前邊加new創建實例。關于這么做的好處,了解java package的好處的都知道那么一些吧,我只還記得避免命名沖突。

2.2、jQuery首先是個Function,既然是個Function,那個就可以new,可以像Function一樣調用,以下將解析幾種jQuery調用方法的源碼:

jQuery(xxx)的時候,轉調到

Js代碼
  1. newjQuery.fn.init(selector,context,rootjQuery)

具體調用時候就需要分析jQuery.PRototype.init函數了。

2.2.1、jQuery(function(){}),當傳入是function的時候,init方法片段:

Js代碼
  1. elseif(jQuery.isFunction(selector)){
  2. returnrootjQuery.ready(selector);
  3. }

此處rootjQuery默認又等于jQuery(document);ready實際上就是在為document注冊load事件,源碼:

Js代碼
  1. ready:function(fn){
  2. //Attachthelisteners
  3. jQuery.bindReady();
  4. //Addthecallback
  5. readyList.done(fn);
  6. returnthis;
  7. }

bindReady方法是通過attachEvent/addEventListener為document注冊了load事件。

Java代碼
  1. bindReady:function(){
  2. if(readyList){
  3. return;
  4. }
  5. readyList=jQuery._Deferred();
  6. //Catchcaseswhere$(document).ready()iscalledafterthe
  7. //browsereventhasalreadyoccurred.
  8. if(document.readyState==="complete"){
  9. //Handleitasynchronouslytoallowscriptstheopportunitytodelayready
  10. returnsetTimeout(jQuery.ready,1);
  11. }
  12. //Mozilla,Operaandwebkitnightliescurrentlysupportthisevent
  13. if(document.addEventListener){
  14. //Usethehandyeventcallback
  15. document.addEventListener("DOMContentLoaded",DOMContentLoaded,false);
  16. //Afallbacktowindow.onload,thatwillalwayswork
  17. window.addEventListener("load",jQuery.ready,false);
  18. //IfIEeventmodelisused
  19. }elseif(document.attachEvent){
  20. //ensurefiringbeforeonload,
  21. //maybelatebutsafealsoforiframes
  22. document.attachEvent("onreadystatechange",DOMContentLoaded);
  23. //Afallbacktowindow.onload,thatwillalwayswork
  24. window.attachEvent("onload",jQuery.ready);
  25. ……
  26. }
  27. }

2.2.2、jQuery(DOMElement)當傳入參數是一dom element的時候,init方法片段:

Js代碼
  1. if(selector.nodeType){
  2. this.context=this[0]=selector;
  3. this.length=1;
  4. returnthis;
  5. }

把dom元素放到了new出來的init對象上,此處this應該是一個對象,應該是個Object的,但是從Chrome調試看,此時this竟然顯示為jQuery.fn.jQuery.init[0],Object.prototype.toString.call(this)結果是”[object Object]”,是個對象,為何顯示這么奇怪呢?在FF里,this顯示為[],按照道理說,對象應該不會這么顯示的才對。

此處把元素賦值為this[0]可以在后續訪問元素的時候,直接用返回實例的[0]來訪問,如果是多個元素,則可以用下標一個個的訪問,后邊看到selector的時候會看到。同時由于后邊把init的原型指向了jQuery的原型,所以這里this的原型方法都是jQuery.prototype的方法:

Js代碼
  1. jQuery.fn=jQuery.prototype=……
  2. jQuery.fn.init.prototype=jQuery.fn;

挖坑,關于原型方法,實例的關系。

2.2.3、如果傳入是body,jQuery(“body”),返回只有一個body元素

Js代碼
  1. if(selector==="body"&&!context&&document.body){
  2. this.context=document;
  3. this[0]=document.body;
  4. this.selector=selector;
  5. this.length=1;
  6. returnthis;
  7. }

2.2.4、jQuery(selector),如jquery.mobile.js中initializePage中$(“:jqmData(role=’page’)”)

Js代碼
  1. //HandleHTMLstrings
  2. if(typeofselector==="string"){
  3. //ArewedealingwithHTMLstringoranID?
  4. if(selector.charAt(0)==="<"&&selector.charAt(selector.length-1)===">"&&selector.length>=3){
  5. //Assumethatstringsthatstartandendwith<>areHTMLandskiptheregexcheck
  6. match=[null,selector,null];
  7. }else{
  8. match=quickExpr.exec(selector);
  9. }
  10. //Verifyamatch,andthatnocontextwasspecifiedfor#id
  11. if(match&&(match[1]||!context)){
  12. ……//省略幾十行,這一段是避免xss攻擊什么的,沒讀懂,以后再來讀
  13. returnthis;
  14. }
  15. //HANDLE:$(expr,$(...))
  16. }elseif(!context||context.jquery){
  17. return(context||rootjQuery).find(selector);
  18. //HANDLE:$(expr,context)
  19. //(whichisjustequivalentto:$(context).find(expr)
  20. }else{
  21. returnthis.constructor(context).find(selector);
  22. }
  23. }

如果傳入的context為空,就從當前對象查找find(selector)否則就從rootjQuery查找,這里rootjQuery是個實力,所以此方法調用就是調用的原型上的find方法:

Js代碼
  1. jQuery.fn.extend({
  2. find:function(selector){
  3. varself=this,
  4. i,l;
  5. ……//此處省略10+行
  6. varret=this.pushStack("","find",selector),
  7. length,n,r;
  8. for(i=0,l=this.length;i<l;i++){
  9. length=ret.length;
  10. jQuery.find(selector,this[i],ret);
  11. if(i>0){
  12. //Makesurethattheresultsareunique
  13. for(n=length;n<ret.length;n++){
  14. for(r=0;r<length;r++){
  15. if(ret[r]===ret[n]){
  16. ret.splice(n--,1);
  17. break;
  18. }
  19. }
  20. }
  21. }
  22. }
  23. returnret;
  24. }

此處又調用到了jQuery.find方法,注意,jQuery是一個Function,這個find跟rootjQuery不同,jQuery.find是function的一個屬性,非嚴格意義上可以簡單的認為類似于java的靜態方法。此find方法實則是Sizzle本身:

jQuery.find = Sizzle;

具體實現還要看selector的內容,可能是getTagByName或者querySelectorAll,如getTagByName(‘name’)、querySelectorAll(“[data-role=’page’]”)。

2.2.5、jQuery()如果傳入為空,則返回不包含元素的jQuery對象:

Js代碼
  1. if(!selector){
  2. returnthis;
  3. }

2.2.6、jQuery(jQuery()),也就是傳一個jQuery實例進去,會創建一個新對象,然后把老對象的內容拷貝到新對象里頭。

綜上,jQuery()返回的是一個jQuery.prototype.init函數的實例,但是由于這個函數的原型指向了jQuery函數的原型,jQuery.prototype上的方法也可以直接在這個實例上調用。同時jQuery會被當成一個數組來使用,根據下標索引提取滿足參數的dom元素。

2.3、jQuery接著:-)也起到命名空間的作用。

雖然jQuery是個function,但是可以在function上添加屬性(這么叫準確么?)然后就可以直接jQuery.method()、jQuery.filed的調了。這里jQuery至少起到了一個命名空間的作用。

既然說到命名空間了,就不得不說jQuery的原型和function的方法,jQuery.method()類似靜態方法,可以通過

Js代碼
  1. jQuery.method=function(){}
  2. jQuery.extend({method:function(){}})

兩種方法來添加。原型方法則通過jQuery.fn.extend / jQuery.prototype.extend來添加。

3、jQuery和Ext都怎么實現繼承的,有什么異同?各有什么優勢?

Javascript是一門基于對象的語言,但不是面向對象,也就是說語言層面沒有提供繼承的語法,但是可以通過應用層面實現繼承。由于把這種實現放到了應用層面,所以實現就變得五花八門了,可以通過拷貝、原型鏈等。了解兩種繼承的調用方式對理解下邊說到的實現原理是很有幫助的。

3.1、Ext(3.x)的繼承跟《JavaScript高級程序設計》里講到的寄生組

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 西贡区| 金山区| 三河市| 安徽省| 中方县| 庆城县| 雷山县| 盐城市| 资阳市| 科技| 修文县| 黄大仙区| 江津市| 宁阳县| 乳源| 桑日县| 信宜市| 内乡县| 岱山县| 积石山| 平远县| 阿鲁科尔沁旗| 普格县| 鸡泽县| 宜宾市| 佛坪县| 屏东县| 秀山| 昔阳县| 洛扎县| 新邵县| 堆龙德庆县| 邻水| 台前县| 阿合奇县| 汝城县| 工布江达县| 扎鲁特旗| 黄冈市| 镇巴县| 乡宁县|