很多人觉得jquery、ext等一些开源js源代码 十分的晦涩,读不懂,遇到问题需要调试也很费劲。其实我个人感觉主要是有几个方面的原因:
1、对一些js不常用的语法、操作符不熟悉
2、某个function中又嵌套了一些内部的function,使得整个代码的层次结构不像java代码那么清晰。
3、js中允许变量先使用后定义,会造成我们看代码时候忽然冒出来一个变量、function,却找不到是在哪里定义的。
那么今天给大家分享一下我的经验,扫清你的障碍。
一、一些晦涩的操作符:
1、(function(){})();
几乎所有的开源js代码开篇都是这样(function(……){……})(……);
下面是Jquery的部分源码:
- (function( window, undefined ) {
- var jQuery = function( selector, context ) {
- // The jQuery object is actually just the init constructor 'enhanced'
- return new jQuery.fn.init( selector, context );
- },
- // Map over jQuery in case of overwrite
- _jQuery = window.jQuery,
- // Map over the $ in case of overwrite
- _$ = window.$,
- ……
- indexOf = Array.prototype.indexOf;
- // Expose jQuery to the global object
- window.jQuery = window.$ = jQuery;
- })(window);
那么这个操作符(function(){})();到底是什么意思呢?
(function(){})中的定义了一个function,紧接着的()表示立即执行这个function。
我们看到Jquery源码第一个()中是定义了一个匿名function( window, undefined ) {};接着末尾有个(window),就表示执行这个匿名function,并传入参数window。
在匿名function( window, undefined ) {}中,定义了一个局部变量jQuery;然后在末尾我们看到Jquery末尾有一句 window.jQuery = window.$ = jQuery; 这句代码就表示,将此前定义的jQuery导出到window对象。这也是为什么我们可以在代码任何地方直接使用$、jQuery对象,因为在这里已经将$、jQuery对象挂载到window下去了,而window.$、window.jQuery与直接使用$、jQuery是没有区别的。
(注意,这个window对象是传入的参数window,而不是浏览器window对象!!一个形参、一个实参。我们可以在定义function的时候,将参数window取名为其他字符。所以我们看到jquery.min.js中这个匿名function变成了(function(E,B){})(window);)
通常(function(){})()用来封装一些私有成员或者公共成员的导出。
2、令人迷惑的","
我们知道“,”一般用于一次定义多个变量、定义多个参数等。像上面的jQuery源码中在var jQuery后面,使用“,”一次定义了很多个变量。
但是,像下面的代码,可能大家就不一定看得懂了:
- //html:<input type="hidden" value="king" id="nameHide"/>
- jQuery(document).ready(function() {
- var showName=function(){
- var value,nameInput=$("#nameHide");
- return nameInput.show(),value=nameInput.val();
- };
- alert(showName());
- });
- //结果:弹出king
这里的“nameInput.show(),value=nameInput.val()”中的“,”运算符的作用是返回","右侧表达式的值。所以,return 后面如果有多个表达式,且表达式之间由","隔开,整个return表达式返回的是最后一个","右侧的表达式的值。
“,”在开源代码中常常被用于return表达式中,以及跟下面我们要讲到的"()"运算符一起使用。
3、“()”广义上的代码包装
我们遇到复杂的逻辑表达式时,我们通常会把需要一起运算的表达式用“()”包起来:(a||b)&&(c||d)
其实,我们可以这样理解:"()"运算符将一个表达式包裹起来作为一个整体进行运算,然后返回这个整体的值。
那么上面的(function(){})()中左侧定义function的()也是这个作用,将这个function给包裹起来,然后返回这个function。我们调用方法一般是a();那么(function(){})的作用就是返回这个function对象,然后(function(){})()右侧的()表示调用这个function。
我们再来看其他的用法:
- //html:<input value="kings" id="name"/><div id="nameErrorTip">输入错误!</div>
- jQuery(document).ready(function() {
- var nameValidate=function(){
- var value,nameInput=$("#name"),nameErrorTip=$("#nameErrorTip");
- return (value=nameInput.val(),value=="king")?(nameErrorTip.hide(),"对了,输入为king!"):(nameErrorTip.show(),"请输入king!");
- };
- alert(nameValidate());
- });
- //结果 nameErrorTip显示,弹出"请输入king!"
- //html:<input value="king" id="name"/><div id="nameErrorTip">输入错误!</div>
- //结果 nameErrorTip隐藏,弹出"对了,输入为king!"
这里“ (value=nameInput.val(),value=="king")”中"()"将里面的表达式作为一个整体进行运算,而里面的表达式又是由","构成的多个表达式组,所以执行的时候会把这多个表达式都执行一次,并且返回最后一个表达式的值!
所以 (value=nameInput.val(),value=="king")执行时,先运算value的值,再判断是否为"king"。如果为king,会执行(nameErrorTip.hide(),"对了,输入为king!")。这个表达式又先将nameErrorTip隐藏,再返回一个"对了,输入为king!"字符串作为 整个return的值。
4、||、&&、if()逻辑让人头晕
||、&&两侧参与运算的是逻辑表达式,if()中也是。但是我们在很多开源代码中看到的||、&&参与运算的表达式看起来却好像不是逻辑表达式……
下面节选一段jQuery.tool中的一段源码:
- e.circular || (f.onBeforeSeek(function(a, b) {
- setTimeout(function() {
- a.isDefaultPrevented()
- || (n.toggleClass(e.disabledClass,
- b <= 0), o.toggleClass(
- e.disabledClass, b >= f
- .getSize()
- - 1))
- }, 1)
- }), e.initialIndex || n.addClass(e.disabledClass)), f.getSize() < 2
- && n.add(o).addClass(e.disabledClass), e.mousewheel
- && a.fn.mousewheel && b.mousewheel(function(a, b) {
- if (e.mousewheel) {
- f.move(b < 0 ? 1 : -1, e.wheelSpeed || 50);
- return !1
- }
- });
这里有多处||、&&。但与运算的表达式却是调用某个函数的返回值。
其实,js中的逻辑表达式是按照真值、假值来分的。true是真值;1是真值;一个对象也是真值;false是假值;""、0是假值。
在js中&&、||不一定都是用来判断一个表达式的逻辑值是true、false,更多的是用来依据真值或者假值执行相应操作!
我们知道,||运算的时候,会先运算左侧的表达式的值,如果为真值,那么真个表达式就为真值,而同时右侧表达式是真值、假值都不重要,因为右侧表达式都不再继续参与运算了。又如果左侧为假值,则继续运算右侧表达式。
&&则先运算左侧表达式,两侧表达式,一个为假值,则整个表达式为假值。
这里关键是这个真值或者假值的运算过程中,我们可以使用上面介绍的","、"()"将一组表达式串起来执行。也就是说,这个表达式可能会很长很长,我甚至可以定义一个function在里面。这些表达式在执行过程中,有可以进行某些附加操作。比如我们希望这个表达式为真值的时候我们做什么,假值的时候做什么,把这些操作用"()"、","串起来作为一个整体运算。
于是就有了上面的复杂代码。
另外,大家注意:下面的写法是等价的:
- if(a){
- b
- }
- //等价于
- a&&(b)
- //b可以是一个function调用表达式,或者是多个语句用","串起来
我们来看个实例吧。是上面例子的升级版。我们加入一个nameInput是否存在的判断:
- jQuery(document).ready(function() {
- var nameValidate=function(){
- var value,nameInput=$("#name"),nameErrorTip=$("#nameErrorTip"),msg;
- msg=(value=nameInput.val(),value=="king")?(nameErrorTip.hide(),"对了,输入为king!"):(nameErrorTip.show(),"请输入king!");
- return (nameInput.length&&nameInput.val()&&nameErrorTip.length&&msg)||"没有找到name输入框或者输入框没有值!";
- };
- alert(nameValidate());
- });
测试:
- //html:<input value="king" id="myName"/>
- //结果:弹出“没有找到name输入框或者输入框没有值!”
- //<input value="king" id="name"/><div id="nameErrorTip">输入错误!</div>
- //结果:弹出“对了,输入为king!”,nameErrorTip被隐藏
return表示中 nameInput.length&&nameInput.val()&&nameErrorTip.length&&msg会先运算 nameInput.length的值,如果length为0则表达式为假值,如果为1则为真值。val()操作也是如此,如果val()结果为""则表达式也是假值。几个表达式之间为&&运算,则表示依次运算几个表达式的值,如果都未真值则返回最后一个表达式的值,由于整个表达式与
"没有找到name输入框或者输入框没有值!"
表达式之间是||运算,所以前面的表达式其中一个表达式为假值则返回||右侧的表达式的值,也就是整个“没有找到name输入框或者输入框没有值!”字符串。
说到这里,我之前写过一篇文章专门说到了&&、||的真值、假值问题。有兴趣的可以去看看。http://my249645546.iteye.com/blog/1553202
谈了这些难以理解的运算符后,大家可能会觉得,这个javascript为什么要搞这些晦涩的运算符呢?
我的理解是因为javascript通常在客户端运行,那么从服务器端将js代码传输到客户端肯定需要耗时。上面的这些运算符都是为了减少代码量。再加上使用压缩工具去掉空格,替换变量名,就可以使用压缩率达到最好。
再这里,我也告诉大家,其实我也非常反对在实际应用中采用这种写法的,因为会对初学者造成阅读障碍。我写这篇文章的目的不是为了让大家以后就这样用,而是告诉大家可以这样用,在一些开源代码中遇到了能看懂。不可为了炫耀而故意写一些晦涩的代码。
最后,为了帮助我们更快的找到变量定义、理清代码整体结构,给大家推荐一个eclipse的js插件:Spket,支持jQuery代码提示哦!
第一个解释起来非常的简单。
只要明白了,匿名函数,函数的执行。就够了!!!
分解出来就是
function niming = readydo() {...}; //定义一个函数
niming(); //执行它
如果把上面转成匿名函数方式:
先直接替换niming:
readydo(){}();
看不清楚,那就加个括号吧
(readydo(){})();
再把readydo变成匿名函数
(function(){})();
ok!
相关推荐
在学习过程中,开发者可以参考这些源代码,逐步解析每个功能的实现,这对于提高jQuery技能和解决问题的能力大有裨益。 具体来说,jQuery攻略源代码可能包含以下知识点: 1. **选择器**: 学习如何使用jQuery选择器...
总的来说,jQuery-1.4.2.js和jQuery-1.4.2.min.js文件代表了jQuery的核心功能,对于想要深入了解JavaScript和前端开发的人员,研究这两个文件的源代码是非常有价值的。通过学习,开发者不仅可以提高工作效率,还能...
这个压缩包文件"jquery源代码 包括示例 包括示例"显然包含了jQuery的核心源代码以及相关的示例,这对于学习和理解jQuery的工作原理及其用法是非常有价值的。 首先,jQuery的核心源代码是JavaScript的一个模块,它...
Jquery学习 Jquery源代码 Jquery数据库操作 Jquery学习 Jquery源代码 Jquery数据库操作 绝对有用,技术含量
在这个压缩包中,你将找到与书中的示例和讲解相关的源代码文件,帮助你深入理解和实践jQuery的各种功能。 首先,我们需要理解jQuery的核心概念。jQuery通过封装JavaScript的原生方法,提供了一套更加易用的API,...
锋利的jQuery 源代码 锋利的jQuery 源代码 锋利的jQuery 源代码 锋利的jQuery 源代码 锋利的jQuery 源代码 锋利的jQuery 源代码 锋利的jQuery 源代码 锋利的jQuery 源代码 锋利的jQuery 源代码
在这个“jQueryMobile源代码”中,我们可以深入研究其内部机制,了解它是如何实现这些功能的。 首先,jQuery Mobile的核心概念是“页面(Pages)”和“面板(Panels)”。页面是应用的基本单元,而面板则用于提供...
Jquery学习 Jquery源代码 Jquery数据库操作 绝对有帮助,请下载,有技术含量的,没有你骂我
这本书的源代码包含了书中各个实例的完整实现,这使得读者能够直接运行和调试代码,加深对jQuery原理的理解。源代码的结构可能按照书中的章节进行组织,每个章节对应一个或多个实例,覆盖了DOM操作、事件处理、选择...
《jQuery基础教程 (Learning jQuery) 完整源代码》涵盖了jQuery这一强大JavaScript库的基本概念、核心功能以及实际应用。jQuery简化了HTML文档遍历、事件处理、动画制作和Ajax交互等任务,使得JavaScript编程变得...
《锋利的jQuery源代码》是一本专门为jQuery初学者设计的学习资源,旨在帮助读者深入理解jQuery的核心机制,通过解析和解读jQuery的源代码,提升JavaScript编程能力。jQuery是一款广泛使用的JavaScript库,它简化了...
**jQuery 简单效果源代码详解** jQuery 是一个广泛使用的 JavaScript 库,它极大地简化了 JavaScript 的DOM操作、事件处理、动画制作等任务。在"jquery 简单效果源代码"中,我们可能涉及到的基本概念和技巧包括: ...
《巧用jQuery源代码》是针对JavaScript库jQuery的一本实践性书籍,旨在帮助开发者深入理解jQuery的内部工作原理,以及如何高效地运用它来优化Web应用。jQuery是一个强大的JavaScript库,简化了HTML文档遍历、事件...
这个压缩包包含了《jQuery Mobile快速入门》这本书的配套源代码,适合初学者深入理解jQuery Mobile的基础用法和实践操作。 jQuery Mobile 的核心特性包括: 1. **统一的用户界面 (UI) 框架**:jQuery Mobile 提供...
这本书的配套源代码提供了丰富的示例和练习,涵盖了jQuery的各个方面,包括选择器、事件处理、DOM操作、动画效果以及AJAX交互等。 在提供的压缩包文件中,我们可以看到以下几个关键文件: 1. **web.config**:这是...
总的来说,《精妙绝伦的jQuery 源代码》这本书不仅提供了对jQuery源码的深度解析,还通过丰富的实例引导读者深入实践,是进阶JavaScript和jQuery开发者的必备参考资料。通过学习这本书,你可以掌握jQuery的核心技术...
本文将深入探讨jQuery 1.2和1.3两个版本的源代码,揭示其中蕴含的核心技术和设计理念,为读者提供一个理解jQuery演进历程的窗口。 一、jQuery 1.2:奠定基石 jQuery 1.2版本在2008年发布,是jQuery发展史上的一座...
【李炎恢jQuery PDF与源代码】集合包含了李炎恢老师关于jQuery的全面教学资源,包括视频教程和PDF文档,这些材料旨在帮助学习者深入理解并掌握jQuery这门强大的JavaScript库。通过配合讲义观看视频,可以有效地复习...
这些文件名称列表揭示了一个关于Web开发的教程结构,主要涵盖了JSP(JavaServer Pages)、Servlet、JavaScript、Ajax和jQuery这五个关键的技术。接下来,我们将详细探讨这些技术及其在实际应用中的重要性。 **JSP...