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 (typeof Ext === ‘undefined‘) {
  2. global.Ext = {};
  3. }

既然Ext是个Object,那jQuery是不是也是个Object呢?NO,来分析下源码,jquery.js:

Js代码

  1. var jQuery = (function() {
  2. // Define a local copy of jQuery
  3. var jQuery = function( selector, context ) {
  4. // The jQuery object is actually just the init constructor ‘enhanced‘
  5. return new jQuery.fn.init( selector, context, rootjQuery );
  6. },
  7. ...//此处省略900行
  8. return jQuery;
  9. })();

此处大概明白了,jQuery是个Function,并且由于此处调用jQuery的时候,有个return,所以var v = jQuery(xxx)和var v = new jQuery(xxx)调用后,v都是同一个函数的实例。在《JavaScript高级程序设计》第18章第一节有提到过这种技巧,叫做作用域安全的构造函数,不过书上提到的形式稍有差异:

Js代码

  1. function Person(name,age){
  2. if(this instanceof Person){
  3. this.name = name;
  4. this.age = age;
  5. }else{
  6. return new Person(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. new jQuery.fn.init(selector,context,rootjQuery)

具体调用时候就需要分析jQuery.prototype.init函数了。

2.2.1、jQuery(function(){}),当传入是function的时候,init方法片段:

Js代码

  1. else if ( jQuery.isFunction( selector ) ) {
  2. return rootjQuery.ready( selector );
  3. }

此处rootjQuery默认又等于jQuery(document);ready实际上就是在为document注册load事件,源码:

Js代码

  1. ready: function( fn ) {
  2. // Attach the listeners
  3. jQuery.bindReady();
  4. // Add the callback
  5. readyList.done( fn );
  6. return this;
  7. }

bindReady方法是通过attachEvent/addEventListener为document注册了load事件。

Java代码

  1. bindReady: function() {
  2. if ( readyList ) {
  3. return;
  4. }
  5. readyList = jQuery._Deferred();
  6. // Catch cases where $(document).ready() is called after the
  7. // browser event has already occurred.
  8. if ( document.readyState === "complete" ) {
  9. // Handle it asynchronously to allow scripts the opportunity to delay ready
  10. return setTimeout( jQuery.ready, 1 );
  11. }
  12. // Mozilla, Opera and webkit nightlies currently support this event
  13. if ( document.addEventListener ) {
  14. // Use the handy event callback
  15. document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
  16. // A fallback to window.onload, that will always work
  17. window.addEventListener( "load", jQuery.ready, false );
  18. // If IE event model is used
  19. } else if ( document.attachEvent ) {
  20. // ensure firing before onload,
  21. // maybe late but safe also for iframes
  22. document.attachEvent( "onreadystatechange", DOMContentLoaded );
  23. // A fallback to window.onload, that will always work
  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. return this;
  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. return this;
  7. }

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

Js代码

  1. // Handle HTML strings
  2. if ( typeof selector === "string" ) {
  3. // Are we dealing with HTML string or an ID?
  4. if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
  5. // Assume that strings that start and end with <> are HTML and skip the regex check
  6. match = [ null, selector, null ];
  7. } else {
  8. match = quickExpr.exec( selector );
  9. }
  10. // Verify a match, and that no context was specified for #id
  11. if ( match && (match[1] || !context) ) {
  12. ……//省略几十行,这一段是避免xss攻击什么的,没读懂,以后再来读
  13. return this;
  14. }
  15. // HANDLE: $(expr, $(...))
  16. } else if ( !context || context.jquery ) {
  17. return (context || rootjQuery).find( selector );
  18. // HANDLE: $(expr, context)
  19. // (which is just equivalent to: $(context).find(expr)
  20. } else {
  21. return this.constructor( context ).find( selector );
  22. }
  23. }

如果传入的context为空,就从当前对象查找find(selector)否则就从rootjQuery查找,这里rootjQuery是个实力,所以此方法调用就是调用的原型上的find方法:

Js代码

  1. jQuery.fn.extend({
  2. find: function( selector ) {
  3. var self = this,
  4. i, l;
  5. ……//此处省略10+行
  6. var ret = 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. // Make sure that the results are unique
  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. return ret;
  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. return this;
  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高级程序设计》里讲到的寄生组合模式类似,这种实现方式复杂,不太容易理解。具体是在当前类和超类之间插入一个空对象,作为子类的原型对象,这个空对象的构造函数的原型指向超类的原型,然后把子类的方法,全部放入到这个空对象上。这样可以做到方法通过原型链实现继承,实例属性通过借用构造函数实现继承。这种方法也是目前最完美的实现方案。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. var options, name, src, copy, copyIsArray, clone,
  3. target = arguments[0] || {}, i = 1,
  4. length = arguments.length, deep = false;
  5. // Handle a deep copy situation
  6. if ( typeof target === "boolean" ) {
  7. deep = target;
  8. target = arguments[1] || {};
  9. // skip the boolean and the target
  10. i = 2;
  11. }
  12. // Handle case when target is a string or something (possible in deep copy)
  13. if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
  14. target = {};
  15. }
  16. // extend jQuery itself if only one argument is passed
  17. if ( length === i ) {
  18. target = this;//如果参数只有一个,target就指向this
  19. --i;
  20. }
  21. for ( ; i < length; i++ ) {
  22. // Only deal with non-null/undefined values
  23. if ( (options = arguments[ i ]) != null ) {
  24. // Extend the base object
  25. for ( name in options ) {//开始复制
  26. src = target[ name ];
  27. copy = options[ name ];
  28. // Prevent never-ending loop
  29. if ( target === copy ) {
  30. continue;
  31. }
  32. // Recurse if we‘re merging plain objects or arrays
  33. if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
  34. if ( copyIsArray ) {
  35. copyIsArray = false;
  36. clone = src && jQuery.isArray(src) ? src : [];
  37. } else {
  38. clone = src && jQuery.isPlainObject(src) ? src : {};
  39. }
  40. // Never move original objects, clone them
  41. target[ name ] = jQuery.extend( deep, clone, copy );
  42. // Don‘t bring in undefined values
  43. } else if ( copy !== undefined ) {
  44. target[ name ] = copy;
  45. }
  46. }
  47. }
  48. }
  49. // Return the modified object
  50. return target;
  51. };

需要特别注意的是这个this,当jQuery.extend的时候,this指的是jQuery.fn.init这个function,后续的方法、属性复制是复制给function的;当通过jQuery.fn.extend的时候,this指向的是原型对象,后续的方法、属性复制是复制给了原型对象。

ExtJS与jQuery的一点细节上的对比,布布扣,bubuko.com

时间: 2024-10-08 02:06:01

ExtJS与jQuery的一点细节上的对比的相关文章

ExtJs和JQuery应用的比较

现在主流的JS框架要数ExtJs和JQuery应用的比较广泛.JQuery属于轻量级的,一般做网站应用比较常见,可见块头小的优势.ExtJs比较庞大,它除了对基本的JS语法和HTML DOM操作方式的封装之外,还提供了一套强大的UI库.在企业级B/S解决方案应用上独占优势.就单说它在原生JS的封装,DOM操作方式封装方面也足以藐视JQuery.下面我就通过对比API,体现两种框架的异曲同工之处.我们已JQuery API为主线,来看看ExtJs是否有替代的方案. 注意一点:ExtJs4.0相对上

jQuery插件-ajaxFileUpload异步上传文件

ajaxFileUpload是前两天学习过程中接触到的一个JQ插件,功能很简单,就是实现异步上传文件的功能. 1.语法介绍 $.ajaxFileUpload([setting]); 参数说明: (1)url——执行上传处理的地址: (2)secureuri——是否启用安全提交,默认为false: (3)fileElementId——需要上传<input type=”file”>控件id属性值: (4)data——自定义参数,即需要额外传递的JSON格式数据: (5)type——请求方式,提交自

ExtJS与JQuery对比

首先分别介绍一下ExtJS和JQuery,然后进行对比分析 一.什么是ExtJS? 1.ExtJS可以用来开发RIA也即富客户端的AJAX应用,是一个用javascript写的,主要用于创建前端用户界面,是一个与后台技术无关的前端ajax框架.因此,可以把ExtJS用在.Net.Java.Php等各种开发语言开发的应用中.ExtJs最开始基于YUI技术,由开发人员JackSlocum开发,通过参考JavaSwing等机制来组织可视化组件,无论从UI界面上CSS样式的应用,到数据解析上的异常处理,

ExtJS与JQuery对照

首先在介绍ExtJS和JQuery,然后进行比较 一个.什么是ExtJS? 1.ExtJS能够用来开发RIA也即富client的AJAX应用,是一个用javascript写的,主要用于创建前端用户界面,是一个与后台技术无关的前端ajax框架.因此.能够把ExtJS用在.Net.Java.Php等各种开发语言开发的应用中. ExtJs最開始基于YUI技术.由开发者JackSlocum开发.通过參考JavaSwing等机制来组织可视化组件,不管从UI界面上CSS样式的应用,到数据解析上的异常处理,都

jquery组件WebUploader文件上传用法详解

这篇文章主要为大家详细介绍了jquery组件WebUploader文件上传用法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件,下文来为各位演示一下关于jquery WebUploader文件上传组件的用法. 使用WebUploader还可以批量上传文件.支持缩略图等等众多参数选项可设置,以及多个事件方法可调用,你可以随心所欲的定制你要的上传组件. 接下来我以图片上

Javascript Fromdata 与jQuery 实现Ajax文件上传以及文件的删除

前端HTML代码: <!DOCTYPE html> <html> <head> <title>ajax</title> <script type="text/javascript" src="js/jquery.js"></script> <meta charset="utf-8" /> <style type="text/css&qu

Jquery form.js文件上传返回JSON数据,在IE下提示下载文件的解决办法,并对返回数据进行正确的解析

Jquery from.js插件上传文件非常方便,但是在ie10以下的版本会弹出下载文件对话框 解决方法: 1.在服务端设置response.setContentType("text/plain"); 2.对返回数据正确解析                这时返回的数据不再是json,不能使用解析json的方法进行解析                       var data1=eval("(" + data+ ")");  //将返回的字符

Javascript Fromdata 与jQuery 实现Ajax文件上传

<!DOCTYPE html> <html> <head> <title>ajax</title> <script type="text/javascript" src="js/jquery.js"></script> <meta charset="utf-8" /> <style type="text/css"> fo

【转】JQuery插件ajaxFileUpload 异步上传文件(PHP版)

前几天想在手机端做个异步上传图片的功能,平时用的比较多的JQuery图片上传插件是Uploadify这个插件,效果很不错,但是由于手机不支持flash,所以不得不再找一个文件上传插件来用了.后来发现ajaxFileUpload这个插件挺不错,所以就用这个插件来做异步上传文件的效果.网上也有很多对ajaxFileUpload插件的使用的文章,不过我发现没有PHP版,所以这次服务器那边的处理就使用PHP语言来处理. 一.先对ajaxFileUpload插件的语法参数进行讲解 原理:ajaxfileu