>

ExtJS与jQuery的少数细节上的自己检查自纠

- 编辑:金沙国际平台登录 -

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和var v = new jQuery调用后,v都是同三个函数的实例。在《JavaScript高档程序设计》第18章第三节有涉及过这种技巧,叫做功效域安全的构造函数,可是书上提到的格局稍有差距:

Js代码

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

这么var p = Person和var p = new Person ,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的时候,转调到

Js代码

  1. newjQuery.fn.init(selector,context,rootjQuery)

切切实实调用时候就供给深入分析jQuery.prototype.init函数了。

2.2.1、jQuery(function,当传入是function的时候,init方法有个别:

Js代码

  1. elseif(jQuery.isFunction){
  2. returnrootjQuery.ready;
  3. }

那边rootjQuery暗中同意又极其jQuery;ready实际上正是在为document注册load事件,源码:

Js代码

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

bindReady方法是因此attach伊夫nt/addEventListener为document注册了load事件。

Java代码

  1. bindReady:function(){
  2. if(readyList){
  3. return;
  4. }
  5. readyList=jQuery._Deferred();
  6. //Catchcaseswhere$.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结果是”[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,如jquery.mobile.js中initializePage中$(“:jqmData(role=’page’)”)

Js代码

  1. //HandleHTMLstrings
  2. if(typeofselector==="string"){
  3. //ArewedealingwithHTMLstringoranID?
  4. if(selector.charAt==="<"&&selector.charAt(selector.length-1)===">"&&selector.length>=3){
  5. //Assumethatstringsthatstartandendwith<>areHTMLandskiptheregexcheck
  6. match=[null,selector,null];
  7. }else{
  8. match=quickExpr.exec;
  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;
  18. //HANDLE:$(expr,context)
  19. //(whichisjustequivalentto:$.find
  20. }else{
  21. returnthis.constructor.find;
  22. }
  23. }

比如传入的context为空,就从前段时间目的查找find不然就从rootjQuery查找,这里rootjQuery是个实力,所以此方法调用正是调用的原型上的find方法:

Js代码

  1. jQuery.fn.extend({
  2. find:function{
  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{
  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;
  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.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的持续跟《JavaScript高档程序设计》里讲到的寄生组合形式类似,这种落成方式复杂,不太轻巧精晓。具体是在时下类和超类之间插入贰个空对象,作为子类的原型对象,这些空对象的构造函数的原型指向超类的原型,然后把子类的法门,全部归入到那些空对象上。那样可以成功方法通过原型链完毕持续,实例属性通过借用构造函数完成一而再。这种情势也是当前最周密的落到实处方案。ExtJS承袭的源码分析参照他事他说加以考察这里。

3.2、jQuery的持续的达成是基于拷贝的,这种达成比较轻易,轻松通晓。可是要介怀的是,jQuery那个function自己和jQuery的原型都有一而再方法,当中jQuery.extend是把艺术、属性拷贝到function上,后续能够直接通过jQuery.method调用;jQuery.fn.extend是把措施、属性拷贝到jQuery的原型上,后续能够透过jQuery实例(实际是jQuery.fn.init的实例,那几个init函数的原型指向jQuery的原型)调用:

Js代码

  1. jQuery.extend=jQuery.fn.extend=function(){
  2. varoptions,name,src,copy,copyIsArray,clone,
  3. target=arguments[0]||{},i=1,
  4. length=arguments.length,deep=false;
  5. //Handleadeepcopysituation
  6. if(typeoftarget==="boolean"){
  7. deep=target;
  8. target=arguments[1]||{};
  9. //skipthebooleanandthetarget
  10. i=2;
  11. }
  12. //Handlecasewhentargetisastringorsomething(possibleindeepcopy)
  13. if(typeoftarget!=="object"&&!jQuery.isFunction{
  14. target={};
  15. }
  16. //extendjQueryitselfifonlyoneargumentispassed
  17. if(length===i){
  18. target=this;//假设参数独有三个,target就针对this
  19. --i;
  20. }
  21. for(;i<length;i++){
  22. //Onlydealwithnon-null/undefinedvalues
  23. if((options=arguments[i])!=null){
  24. //Extendthebaseobject
  25. for(nameinoptions){//初步复制
  26. src=target[name];
  27. copy=options[name];
  28. //Preventnever-endingloop
  29. if(target===copy){
  30. continue;
  31. }
  32. //Recurseifwe'remergingplainobjectsorarrays
  33. if(deep&©&&(jQuery.isPlainObject||(copyIsArray=jQuery.isArray{
  34. if(copyIsArray){
  35. copyIsArray=false;
  36. clone=src&&jQuery.isArray?src:[];
  37. }else{
  38. clone=src&&jQuery.isPlainObject?src:{};
  39. }
  40. //Nevermoveoriginalobjects,clonethem
  41. target[name]=jQuery.extend(deep,clone,copy);
  42. //Don'tbringinundefinedvalues
  43. }elseif(copy!==undefined){
  44. target[name]=copy;
  45. }
  46. }
  47. }
  48. }
  49. //Returnthemodifiedobject
  50. returntarget;
  51. };

亟待非常注意的是其一this,当jQuery.extend的时候,this指的是jQuery.fn.init那么些function,后续的章程、属性复制是复制给function的;当通过jQuery.fn.extend的时候,this指向的是原型对象,后续的艺术、属性复制是复制给了原型对象。

本文由编程发布,转载请注明来源:ExtJS与jQuery的少数细节上的自己检查自纠