- 浏览: 522022 次
- 性别:
- 来自: 北京
博客专栏
-
jQuery技术内幕
浏览量:201221
最新评论
-
青春依旧:
学习html5哪里好?当然华清远见是首选!
[原创] jQuery源码分析-01总体架构 -
追梦1819:
[size=x-small][color=red][/colo ...
[原创] jQuery源码分析-04 选择器-Sizzle-设计思路 -
niuqiang2008:
学习学习
[原创] jQuery源码分析-04 选择器-Sizzle-工作原理 -
liuweihug:
jquery 解析正则表达式及常见的Regex规则和表达式 - ...
[原创] jQuery源码分析-02正则表达式-RegExp-常用正则表达式 -
liang8768:
mark!!!
[原创] jQuery源码分析-00前言开光
1. 总体架构
1.1 自调用匿名函数 self-invoking anonymous function
打开jQuery源码,首先你会看到这样的代码结构:
(function( window, undefined ) { // jquery code })(window); |
1. 这是一个自调用匿名函数。什么东东呢?在第一个括号内,创建一个匿名函数;第二个括号,立即执行
2. 为什么要创建这样一个“自调用匿名函数”呢?
通过定义一个匿名函数,创建了一个“私有”的命名空间,该命名空间的变量和方法,不会破坏全局的命名空间。这点非常有用也是一个JS框架必须支持的功能,jQuery被应用在成千上万的JavaScript程序中,必须确保jQuery创建的变量不能和导入他的程序所使用的变量发生冲突。
3. 匿名函数从语法上叫函数直接量,JavaScript语法需要包围匿名函数的括号,事实上自调用匿名函数有两种写法(注意标红了的右括号):
(function() { console.info( this ); console.info( arguments ); }( window ) ); |
(function() { console.info( this ); console.info( arguments ); })( window ); |
4. 为什么要传入window呢?
通过传入window变量,使得window由全局变量变为局部变量,当在jQuery代码块中访问window时,不需要将作用域链回退到顶层作用域,这样可以更快的访问window;这还不是关键所在,更重要的是,将window作为参数传入,可以在压缩代码时进行优化,看看jquery-1.6.1.min.js:
(function(a,b){})(window); // window 被优化为 a |
5. 为什么要在在参数列表中增加undefined呢?
在 自调用匿名函数 的作用域内,确保undefined是真的未定义。因为undefined能够被重写,赋予新的值。
undefined = "now it's defined"; alert( undefined ); |
浏览器测试结果:
浏览器 |
测试结果 |
结论 |
ie |
now it's defined |
可以改变 |
firefox |
undefined |
不能改变 |
chrome |
now it's defined |
可以改变 |
opera |
now it's defined |
可以改变 |
6. 注意到源码最后的分号了吗?
分号是可选的,但省略分号并不是一个好的编程习惯;为了更好的兼容性和健壮性,请在每行代码后加上分号并养成习惯。
1.2 总体架构
接下来看看在 自调用匿名函数 中都实现了什么功能,按照代码顺序排列:
(function( window, undefined ) { // 构造jQuery对象 var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery ); } // 工具函数 Utilities // 异步队列 Deferred // 浏览器测试 Support // 数据缓存 Data // 队列 queue // 属性操作 Attribute // 事件处理 Event // 选择器 Sizzle // DOM遍历 // DOM操作 // CSS操作 // 异步请求 Ajax // 动画 FX // 坐标和大小 window.jQuery = window.$ = jQuery; })(window); |
从上边的注释看,jQuery的源码结构相当清晰、条理,不像代码那般晦涩和让人纠结。
后边的章节基本将以这个顺序展开。
1.3 下节预告
如果你看过jQuery源码,很快就会发现这里到处充斥着正则表达式,而很多JavaScript开发人员又疏于正则基础知识,为了扫清这个障碍,下一章将先温习JavaScript正则表达式的基础知识,再详细剖析jQuery中的正则表达式。
在正式开始分析源码之前,还有没有要准备的基础知识呢?
当然有。比如JavaScript API中的类和对象,如果你不熟练的话,至少手头要有一本参考手册。
除了正则,其他的知识点会在分析过程中穿插讲解,不计划辟出新的章节。
评论
<script> $(function(){ window.test = function(){ alert('test'); }; }); // ok $(function(){ test(); }); // fail (function(){ window.test(); })(); // fail $(function(w){ w.test(); }(window)); // fail (function(w){ w.test(); })(window); </script>
三个fail是因为它们执行时,window.test = function(){...}还没有执行,如果这句先执行过了,就都正常执行了
init: function( selector, context, rootjQuery ) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; } }这不应该是个对象么
如:var module1 = (function(){
_count = 0;
var m1 = function(){
//...
};
var m2 = function(){
//...
};
return {
m1 : m1,
m2 : m2
};
})();
alert(module1._count);---输出undefined
可不可以这样理解。因为你的module1是自执行函数为其赋的值。而这个自执行函数执行后返回值为仅仅包含m1、m2变量的对象。你使用 alert出 module1这个已经赋值过的对象中找_count当然不能找到了。不知道可不可以这样理解……
刚刚引错了。。应该是这个。。_count是全局变量吧。。。
基本类型按值传递,对象传入引用,函数内部的 window 即全局 window。
看这样一个例子
<script type="text/javascript"> function setName(obj){ obj.name = "xiaobai"; obj = new Object(); obj.name = "xiaohei"; } var dog = new Object(); setName(dog); console.log(dog.name); /*输出 *xiaobai */ </script>
JS的函数传参应该都是传值吧,即使是一个对象作为参数,也只是传递的这个对象的引用的一个复制。难道我理解错了??
你传递的obj指针是按值传递的,函数调用结束后obj还指向调用前的obj
是不是因为_count成为了全局变量啊。。。console.log(_count)就可以。。
基本类型按值传递,对象传入引用,函数内部的 window 即全局 window。
看这样一个例子
<script type="text/javascript"> function setName(obj){ obj.name = "xiaobai"; obj = new Object(); obj.name = "xiaohei"; } var dog = new Object(); setName(dog); console.log(dog.name); /*输出 *xiaobai */ </script>
JS的函数传参应该都是传值吧,即使是一个对象作为参数,也只是传递的这个对象的引用的一个复制。难道我理解错了??
var dog = new Object(); dog 是一个引用,指向一块内存,将dog传入setName,在setName中修改name属性,能直接反应到dog中,对传入的引用重新赋值,让它重新指向另外一个区域,然后修改name属性,因为引用重置了,这个修改只会对内部那个新对象有用,对外部的dog已无影响。
引用《javascript高级程序设计》书中的一句话回答:当在函数内部重写引用对象obj时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即销毁。
可以把ECMAScript函数的参数想想成局部变量。
基本类型按值传递,对象传入引用,函数内部的 window 即全局 window。
看这样一个例子
<script type="text/javascript"> function setName(obj){ obj.name = "xiaobai"; obj = new Object(); obj.name = "xiaohei"; } var dog = new Object(); setName(dog); console.log(dog.name); /*输出 *xiaobai */ </script>
JS的函数传参应该都是传值吧,即使是一个对象作为参数,也只是传递的这个对象的引用的一个复制。难道我理解错了??
var dog = new Object(); dog 是一个引用,指向一块内存,将dog传入setName,在setName中修改name属性,能直接反应到dog中,对传入的引用重新赋值,让它重新指向另外一个区域,然后修改name属性,因为引用重置了,这个修改只会对内部那个新对象有用,对外部的dog已无影响。
请教个问题 jquery $(selector)方法 $.trim()
jquery 即使方法也是对象
怎么做到的?
这块很不理解 劳烦 博主解答!
查看jQuery1.6.4源代码如下:
(function( window, undefined ) {
// Use the correct document accordingly with window argument (sandbox)
var document = window.document,
navigator = window.navigator,
location = window.location;
.......
该trim函数是通过jQuery的extend方法实现继承的。这就需要你理解jQuery.extend的功能了。
不知道说的这么多你理解否?
多谢楼主解答,醍醐灌顶呀
<script> $(function(){ window.test = function(){ alert('test'); }; }); // ok $(function(){ test(); }); // fail (function(){ window.test(); })(); // fail $(function(w){ w.test(); }(window)); // fail (function(w){ w.test(); })(window); </script>
请教个问题 jquery $(selector)方法 $.trim()
jquery 即使方法也是对象
怎么做到的?
这块很不理解 劳烦 博主解答!
查看jQuery1.6.4源代码如下:
(function( window, undefined ) {
// Use the correct document accordingly with window argument (sandbox)
var document = window.document,
navigator = window.navigator,
location = window.location;
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 );
},
......
return jQuery;//返回的这个就是var jQuery = function( selector, context ) {}
})();
......
window.jQuery = window.$ = jQuery;
})(window);
//解决你的问题1. $(selector)
调用的是如下代码:
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
}//说到最后还是 new 了jQuery.fn.init的一个实例,使用selector作为参数。
//解决你的问题2. $.trim()
// Use native String.trim function wherever possible
jQuery.extend({
......
trim: trim ?
function( text ) {
return text == null ?
"" :
trim.call( text );
} :
// Otherwise use our own trimming functionality
function( text ) {
return text == null ?
"" :
text.toString().replace( trimLeft, "").replace( trimRight, "" );
},
......});
该trim函数是通过jQuery的extend方法实现继承的。这就需要你理解jQuery.extend的功能了。
不知道说的这么多你理解否?
基本类型按值传递,对象传入引用,函数内部的 window 即全局 window。
看这样一个例子
<script type="text/javascript"> function setName(obj){ obj.name = "xiaobai"; obj = new Object(); obj.name = "xiaohei"; } var dog = new Object(); setName(dog); console.log(dog.name); /*输出 *xiaobai */ </script>
JS的函数传参应该都是传值吧,即使是一个对象作为参数,也只是传递的这个对象的引用的一个复制。难道我理解错了??
你传递的obj指针是按值传递的,函数调用结束后obj还指向调用前的obj
在函数setName内部给obj参数添加了一个属性name、然后将引用变量obj重新赋值为空对象。这个obj的重新定义只是在函数内部起到效果、函数之外obj还是指向原来的地址。所以输出:xiaobai。我可以这样解释吗?
请教个问题 jquery $(selector)方法 $.trim()
jquery 即使方法也是对象
怎么做到的?
这块很不理解 劳烦 博主解答!
基本类型按值传递,对象传入引用,函数内部的 window 即全局 window。
看这样一个例子
<script type="text/javascript"> function setName(obj){ obj.name = "xiaobai"; obj = new Object(); obj.name = "xiaohei"; } var dog = new Object(); setName(dog); console.log(dog.name); /*输出 *xiaobai */ </script>
JS的函数传参应该都是传值吧,即使是一个对象作为参数,也只是传递的这个对象的引用的一个复制。难道我理解错了??
你传递的obj指针是按值传递的,函数调用结束后obj还指向调用前的obj
如:var module1 = (function(){
_count = 0;
var m1 = function(){
//...
};
var m2 = function(){
//...
};
return {
m1 : m1,
m2 : m2
};
})();
alert(module1._count);---输出undefined
可不可以这样理解。因为你的module1是自执行函数为其赋的值。而这个自执行函数执行后返回值为仅仅包含m1、m2变量的对象。你使用 alert出 module1这个已经赋值过的对象中找_count当然不能找到了。不知道可不可以这样理解……
如:var module1 = (function(){
_count = 0;
var m1 = function(){
//...
};
var m2 = function(){
//...
};
return {
m1 : m1,
m2 : m2
};
})();
alert(module1._count);---输出undefined
看这样一个例子
<script type="text/javascript"> function setName(obj){ obj.name = "xiaobai"; obj = new Object(); obj.name = "xiaohei"; } var dog = new Object(); setName(dog); console.log(dog.name); /*输出 *xiaobai */ </script>
JS的函数传参应该都是传值吧,即使是一个对象作为参数,也只是传递的这个对象的引用的一个复制。难道我理解错了??
obj是dog的一个复制,所以修改obj指向别的对象对dog没影响。
基本类型按值传递,对象传入引用,函数内部的 window 即全局 window。
看这样一个例子
<script type="text/javascript"> function setName(obj){ obj.name = "xiaobai"; obj = new Object(); obj.name = "xiaohei"; } var dog = new Object(); setName(dog); console.log(dog.name); /*输出 *xiaobai */ </script>
JS的函数传参应该都是传值吧,即使是一个对象作为参数,也只是传递的这个对象的引用的一个复制。难道我理解错了??
这个还真没想到
发表评论
-
[原创] jQuery源码分析-04 选择器-Sizzle-设计思路
2011-11-14 20:59 6878作者:nuysoft/高云 QQ:47214707 Em ... -
[原创] jQuery源码分析-04 选择器-Sizzle-工作原理
2011-11-13 23:45 7915作者:nuysoft/高云 QQ:47214707 EM ... -
[原创] jQuery源码分析-02正则表达式-RegExp-常用正则表达式
2011-10-27 01:29 46679作者:nuysoft/JS攻城师/ ... -
[原创] jQuery源码分析-jQuery中的循环技巧
2011-10-27 00:36 14578作者:nuysoft/JS攻城师/高云 QQ:47214707 ... -
[原创] jQuery源码分析-10事件处理-Event-DOM-ready
2011-10-20 01:20 10631作者:nuysoft/JS攻城师/ ... -
[原创] jQuery源码分析-Java工程师应该向jQuery学习的8点建议
2011-10-18 23:56 12279作者:nuysoft/高云 QQ:47214707 EM ... -
[原创] jQuery源码分析-10事件处理-Event-事件绑定与删除-bind/unbind+live/die+delegat/undelegate
2011-10-18 22:31 15700作者:nuysoft/高云 QQ:47214707 EM ... -
[原创] jQuery源码分析-10事件处理-Event-源码结构
2011-10-17 01:01 12151作者:nuysoft/高云 QQ:47214707 EMail ... -
[原创] jQuery源码分析-07数据缓存-Cache
2011-10-13 19:55 12172作者:nuysoft/高云 QQ:47214707 EMail ... -
[原创] jQuery源码分析-06浏览器测试-Support
2011-10-13 19:19 9954作者:nuysoft/高云 QQ:47214707 EMail ... -
[原创] jQuery源码分析系列目录(持续更新)
2011-10-12 12:30 29404作者:nuysoft/高云 QQ:47214707 E ... -
[原创] jQuery源码分析-10事件处理-Event-概述和基础知识
2011-10-12 00:16 12043作者:nuysoft/高云 Q ... -
[原创] jQuery源码分析-08队列 Queue
2011-10-10 23:48 10837作者:nuysoft/高云 Q ... -
[原创] jQuery源码分析-03构造jQuery对象-工具函数
2011-09-29 23:21 29822作者:nuysoft/高云 QQ:47214707 E ... -
[原创] jQuery源码分析-15AJAX-类型转换器
2011-09-29 02:25 7446作者:nuysoft/高云 QQ:47214707 EM ... -
[原创] jQuery源码分析-03构造jQuery对象-源码结构和核心函数
2011-09-28 02:20 53016作者:nuysoft/高云 QQ:47214707 EMail ... -
[原创] jQuery源码分析-如何做jQuery源码分析
2011-09-27 00:22 15029近期在ITEYE陆续写了几篇jQuery源码分析,乐在其 ... -
[原创] jQuery源码分析-17尺寸和大小 Dimensions & Offset
2011-09-25 22:05 7077边读边写,不正确的地方,还请各位告诉我,多多交流共同学习, ... -
[原创] jQuery源码分析-15AJAX-前置过滤器和请求分发器
2011-09-23 00:09 13313边读边写,不正确的 ... -
[原创] jQuery源码分析-00前言开光
2011-09-21 23:42 47039jQuery源码分析 - 前言 jQuery凭借简洁的语法和 ...
相关推荐
jQuery源码分析-插件
jQuery源码分析-初步
jQuery源码分析-事件(1).
《jQuery源码分析-总体架构解析》 在深入探究jQuery的源码之前,我们首先要理解其总体架构的设计理念。jQuery以其高效、易用的特性深受开发者喜爱,而这背后离不开其精心设计的架构。本文将围绕jQuery的核心构造...
jQuery源码分析-魔术方法
jQuery源码分析-事件(2).
《jQuery UI与jQuery插件深度解析——以jquery-ui-1.8.2.custom.min.js为例》 在Web开发领域,jQuery库以其简洁易用的API和强大的功能深受开发者喜爱。而jQuery UI作为jQuery的一个扩展,提供了丰富的用户界面组件...
### jQuery源码分析—构造jQuery对象 #### 一、源码结构概览 根据所提供的文件内容,本节将深入分析如何构建jQuery对象及其核心构造逻辑。首先,让我们从整体上理解jQuery构造函数的设计思路。 ##### 总体结构 ...
这个压缩包包含两个关键文件:`jquery-ui-1.8.16.custom.min.js` 和 `jquery-ui-1.8.16.custom.css`,这些都是jQuery UI的特定版本,即1.8.16。这个版本在当时是一个广泛使用的稳定版本,提供了丰富的功能和组件。 ...
<script src="./public/js/jquery-ui-1.10.3.min.js"> <script src="./public/js/jquery.datepicker-zh-CN.js"></script> <link href="./public/css/jqueryui/jquery-ui-1.10.3.min.css" rel="stylesheet"> $( "#...
jquery插件jquery-ui-timepicker-addon.j
jquery-ui-日期框扩展成时间框 jquery-ui时间框 基于别人的代码进行修改 jquery-ui-1.8.16.custom.css文件末尾加入以下代码 .ui-timepicker-div .ui-widget-header{ margin-bottom: 8px; } .ui-timepicker-div dl{ ...
jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码jQuery源码...
jquery-migrate-3.0.0.min.js 含源码 包含以下文件: jquery-migrate-3.0.0.min.js jquery-migrate-3.0.0.js // 这个是源码哦 截至2017.11.21, jQuery3.x 最新最稳定版本