- 浏览: 377793 次
- 性别:
- 来自: 杭州
-
文章分类
最新评论
-
surpassno:
很不错,学习了
一个对象占用多少字节? -
ysyzww:
你这么牛逼,你父母知道吗
maven使用技巧 -
妖人不要跑:
JDK中反序列化对象的过程(ObjectInputStream#readObject) -
lanhz:
谢楼主,构建成功了
Mac OSX 10.9 上build openjdk8和openjdk7 -
zqb666kkk:
通过了吗 ?????
淘宝北京专场java面试题(2011-12-31)
首先说明这不是一篇完整解读ExtJS和jQuery所有方面差异的文章,只是针对我个人刚看了两天的jQuery产生的一些疑问的整理。之前用过一段时间ExtJS,了解ExtJS的一些机制。现在做移动开发,又选定了jquery mobile,要写控件,所以需要了解jquery。(不过换工作之后应该不会再用jQuery了,坑估计是短期内填不上了)
1、jQuery是个什么东西?Ext是什么东西?(此处不是指两个框架,而是指我们在写程序的时候,经常用到的两个关键字--暂时称之为关键字)
之前用的是ExtJS,Ext是个Object,通过字面量创建的,Ext.js文件里,3.3.1版:
Ext = { version : '3.3.1', versionDetail : { major : 3, minor : 3, patch : 1 } };
4.0版本,此处global == window:
if (typeof Ext === 'undefined') { global.Ext = {}; }
既然Ext是个Object,那jQuery是不是也是个Object呢?NO,来分析下源码,jquery.js:
var jQuery = (function() { // Define a local copy of jQuery var jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context, rootjQuery ); }, ...//此处省略900行 return jQuery; })();
此处大概明白了,jQuery是个Function,并且由于此处调用jQuery的时候,有个return,所以var v = jQuery(xxx)和var v = new jQuery(xxx)调用后,v都是同一个函数的实例。在《JavaScript高级程序设计》第18章第一节有提到过这种技巧,叫做作用域安全的构造函数,不过书上提到的形式稍有差异:
function Person(name,age){ if(this instanceof Person){ this.name = name; this.age = age; }else{ return new Person(name,age); } }
这样var p = Person('a',21)和var p = new Person('a',21) ,p就都是Person实例了,如果去掉if判断和else后边的内容,第一种调用p是undefined。
在jquery.js最后,把变量jQuery赋值给了$,后续可以通过$这种简写使用jQuery,算是一个简写的别名吧:
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)的时候,转调到
new jQuery.fn.init(selector,context,rootjQuery)
具体调用时候就需要分析jQuery.prototype.init函数了。
2.2.1、jQuery(function(){}),当传入是function的时候,init方法片段:
else if ( jQuery.isFunction( selector ) ) { return rootjQuery.ready( selector ); }
此处rootjQuery默认又等于jQuery(document);ready实际上就是在为document注册load事件,源码:
ready: function( fn ) { // Attach the listeners jQuery.bindReady(); // Add the callback readyList.done( fn ); return this; }
bindReady方法是通过attachEvent/addEventListener为document注册了load事件。
bindReady: function() { if ( readyList ) { return; } readyList = jQuery._Deferred(); // Catch cases where $(document).ready() is called after the // browser event has already occurred. if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready return setTimeout( jQuery.ready, 1 ); } // Mozilla, Opera and webkit nightlies currently support this event if ( document.addEventListener ) { // Use the handy event callback document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); // A fallback to window.onload, that will always work window.addEventListener( "load", jQuery.ready, false ); // If IE event model is used } else if ( document.attachEvent ) { // ensure firing before onload, // maybe late but safe also for iframes document.attachEvent( "onreadystatechange", DOMContentLoaded ); // A fallback to window.onload, that will always work window.attachEvent( "onload", jQuery.ready ); …… } }
2.2.2、jQuery(DOMElement)当传入参数是一dom element的时候,init方法片段:
if ( selector.nodeType ) { this.context = this[0] = selector; this.length = 1; return this; }
把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的方法:
jQuery.fn = jQuery.prototype = …… jQuery.fn.init.prototype = jQuery.fn;
挖坑,关于原型方法,实例的关系。
2.2.3、如果传入是body,jQuery(“body”),返回只有一个body元素
if ( selector === "body" && !context && document.body ) { this.context = document; this[0] = document.body; this.selector = selector; this.length = 1; return this; }
2.2.4、jQuery(selector),如jquery.mobile.js中initializePage中$(“:jqmData(role=’page’)”)
// Handle HTML strings if ( typeof selector === "string" ) { // Are we dealing with HTML string or an ID? if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ]; } else { match = quickExpr.exec( selector ); } // Verify a match, and that no context was specified for #id if ( match && (match[1] || !context) ) { ……//省略几十行,这一段是避免xss攻击什么的,没读懂,以后再来读 return this; } // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { return (context || rootjQuery).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor( context ).find( selector ); } }
如果传入的context为空,就从当前对象查找find(selector)否则就从rootjQuery查找,这里rootjQuery是个实力,所以此方法调用就是调用的原型上的find方法:
jQuery.fn.extend({ find: function( selector ) { var self = this, i, l; ……//此处省略10+行 var ret = this.pushStack( "", "find", selector ), length, n, r; for ( i = 0, l = this.length; i < l; i++ ) { length = ret.length; jQuery.find( selector, this[i], ret ); if ( i > 0 ) { // Make sure that the results are unique for ( n = length; n < ret.length; n++ ) { for ( r = 0; r < length; r++ ) { if ( ret[r] === ret[n] ) { ret.splice(n--, 1); break; } } } } } return ret; }
此处又调用到了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对象:
if (!selector ) { return this; }
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()类似静态方法,可以通过
jQuery.method=function(){} 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的原型)调用:
jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; } // extend jQuery itself if only one argument is passed if ( length === i ) { target = this;//如果参数只有一个,target就指向this --i; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( name in options ) {//开始复制 src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; };
需要特别注意的是这个this,当jQuery.extend的时候,this指的是jQuery.fn.init这个function,后续的方法、属性复制是复制给function的;当通过jQuery.fn.extend的时候,this指向的是原型对象,后续的方法、属性复制是复制给了原型对象。
发表评论
-
Session cookie、持久化Cookie和P3P头在跨域访问时候的行为
2012-08-03 20:24 3216浏览器中,Cookie分为两类,Session Cookie和 ... -
JavaScript学习之四 — 点滴之匿名函数
2011-09-28 00:44 1689前几天椰子在微博上发了消息说匿名函数也可以有名字,我就想了半天 ... -
JavaScript的instanceof有bug?
2011-01-03 17:08 2395前几天,又是工作上的问题。发现一个对象实例在instanceo ... -
浏览器页面,禁用刷新
2011-01-03 15:37 3098近来工作中遇到一问题,查看单据信息的时候,要禁用刷新功能。这里 ... -
Ext源码解析之二 - ComboBox组件
2010-12-11 00:43 0一、例子二、源码分析三、扩展 -
Ext源码解读之一 -- extend的实现
2010-10-26 23:02 2290先看一个例子: Gmis.ex ... -
JavaScript学习之三 — JavaScript实现继承的7种方式
2010-10-14 23:11 1725本文列举了《JavaScript高级程序设计:第二版》书中讲到 ... -
JavaScript学习之二 — JavaScript创建对象的8种方式
2010-10-11 22:56 1141本文列举了《JavaScript高级程序设计:第二版》书中讲到 ... -
JavaScript学习之一 — 开发调试工具
2010-10-10 11:42 13411、开发工具 一般使用eclipse的spket插件做 ...
相关推荐
通过使用 jQuery EasyUI,开发者可以避免编写复杂的 JavaScript 代码以及深入研究 CSS 样式细节,仅需掌握基本的 HTML 标签即可实现丰富的 UI 效果。 - **官方网站**:[http://www.jeasyui.com]...
7. **DWR与其他技术的集成**:DWR可以与各种前端框架如jQuery、Dojo、ExtJS等无缝集成,提升Web应用的界面效果和用户体验。同时,DWR也可以与其他后端技术如Spring、Hibernate等配合,构建完整的Web应用程序。 以上...
该资源为joblib-1.1.0-py2.py3-none-any.whl,欢迎下载使用哦!
内容概要:本文详细介绍了如何使用MATLAB/Simulink R2015b搭建Buck-Boost变换器的开环和闭环控制仿真模型。首先,作者解释了Buck-Boost变换器的基本构成及其在电源设计中的重要性。接着,逐步指导读者构建开环模型,包括设置关键参数如PWM频率、占空比、输入电压等,并展示了开环控制下的输出特性。随后,引入了PID控制器进行闭环控制,强调了PID参数的选择与调整方法,以及如何通过增加电压采样和误差比较来提高系统的稳定性。此外,还分享了一些常见的仿真错误及解决方案,如电感值选取不当、二极管模型过于理想等问题。最后,提供了几个有趣的实验案例,如动态改变占空比、突变负载等,以展示闭环控制的优势。 适合人群:具有一定电力电子和MATLAB/Simulink基础的技术人员或学生。 使用场景及目标:适用于希望深入理解Buck-Boost变换器工作原理及其控制策略的研究者和技术爱好者。通过动手实践,掌握开环与闭环控制的区别,学会优化PID参数,提升电源设计能力。 其他说明:文中附有多处代码片段和实用技巧,有助于读者更好地理解和应用所学知识。同时提醒读者注意不同MATLAB版本间的兼容性问题。
2023年上海市高等学校计算机等级考试.docx
能检测死锁,输出相关代码便于排查
电子商务物流业务管理教材.pptx
基于stm32的控制底层
2023年全国计算机等级考试三级数据库试题.doc
2023年计算机二级考试操作题真题.doc
2023年自考管理系统中计算机应用试题及答案.doc
资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。
2023年电子科技秋网与网站设计在线作业.doc
内容概要:本文详细介绍了基于脉振高频电压注入的无速度传感器控制系统。该方法通过向电机定子绕组注入高频电压信号(如2kHz),利用高频响应电流中的转子位置信息进行实时定位。文中展示了具体的代码实现,包括信号注入、带通滤波、正交锁相环以及位置跟踪观测器的设计。此外,讨论了参数整定、抗干扰措施(如伪随机频移键控)和实际调试过程中遇到的问题及其解决方案。该方法适用于低速或零速情况,能够显著提高位置估计的准确性。 适合人群:从事电机控制、自动化控制领域的工程师和技术研究人员。 使用场景及目标:①用于工业伺服系统中,特别是那些对成本敏感或安装空间有限的应用;②解决传统方法在低速或零速情况下无法准确估计转子位置的问题;③提供一种可靠的无速度传感器控制方案,减少硬件成本和维护难度。 其他说明:该方法虽然在低速时表现出色,但在高速时精度有所下降,可以通过混合观测策略进行优化。同时,实际应用中需要注意高频信号带来的额外损耗和参数敏感性问题。
2023年计算机二级基础知识重点总结.docx
该资源为joblib-1.1.0.tar.gz,欢迎下载使用哦!
An-225大型运输机实体装配模型由225个实体零件基元组成,分为21个子装配模块。 该模型是通过缩放一个基本的8.5英寸x11英寸三视图原理图而开发的。 因此,其精度有所降低。
matlab
2024年大数据软件项目深度研究分析报告.docx
2023年四川省一级计算机等级考试训练题.doc