您的位置:首页 > Web前端 > JQuery

jQuery源码学习 之 立即调用 ---- day2

2015-09-17 20:41 537 查看
1. 立即调用表达式

任何库与框架设计的第一个要点就是解决命名空间与变量污染问题,jQuery就是利用了JavaScript函数作用域的特性,采用立即调用表达式包裹了自身的方法来解决这个问题。

2. jQuery立即调用表达式有三种写法

写法一:

(function(window, factory) {
factory(window);
}(this, function() {
return function() {
// jQuery的调用
}
}));
上面的代码嵌套了2个函数,而且把一个函数作为参数传递给另一个函数中并且执行,这种方式有点复杂,简化一下的写法如下:

写法二:

var factory = function() {
return function() {
//执行方法
}
};
var jQuery = factory();
上面的代码效果和方法一是等同的,但是这个factory有点变成了简单的工厂方法模式,需要自己调用,不像是一个单例的jQuery类,所以我们需要改成“自执行”,而不是另外调用。

写法三:

(function(window, undefined) {
var jQuery = function() {
// ...
};
})(window);
从上面的代码可以看出,自动初始化这个函数,让其只构建一次。这种写法的优势有:

(1)window和undefined都是为了减少变量查找所经过的scope作用域。当window通过传递给闭包内部之后,在闭包内部使用它的时候,可以把它当成一个局部变量,显然比原先在window scope下查找的时候要快一些。

(2)undefined也是同样的道理,其实这个undefined并不是JavaScript数据类型的undefined,而是一个普通普通的变量名,只是因为没有给它传值,它的值就是undefined,undefined并不是JavaScript的保留字。

3. jQuery用这样的一个外层包裹的原理

这里要区分两个概念:匿名函数和自执行。顾名思义,匿名函数就是没有函数名的函数,也就是不存在外部引用。但是是否存在像下面的代码实现呢:

function() {
// code
}
上面这种写法错了,声名了它但是又不给名字又没有使用,所以在语法上是错误的,那么要怎么去执行一个匿名函数呢?要调用一个匿名函数,必须要有方法可以定位它、引用它,所以,我们要取一个名字:

var jQuery = function() {
// code
};
jQuery使用()将匿名函数括起来,然后后面再加一对小括号(包含参数列表),那么这小括号能把我们的表达式组合分块,并且每一块(也就是一对小括号)都有一个返回值。这个返回值实际上也就是小括号中表达式的返回值。所以,当我们用一对小括号把匿名函数括起来时,实际上小括号返回的就是一个匿名函数的Function对象。因此,小括号对加上匿名函数就如同有名字函数般被我们取得它的引用位置了。所以如果在这个引用变量后面再加上参数列表,就会衬布普通函数的调用形式。

最后,我们回到写法一,看看jQuery利用写法三的写法,然后把整个函数作为参数传递给另外一个函数,主要是为了判断jQuery在不同平台下的加载逻辑,主流的库一般都有对AMD和CommonJS的支持代码,看看jQuery的代码:

if(typeof module === "object" && typeof module.exports === "object") {
module.exports = global.document ? factory(global, true) : function(w) {
if(!w.document) {
throw new Error("jQuery requires a window with a document");
}
return factory(w);
}
} else {
factory(global);
}


总结:

全局变量是魔鬼,匿名函数可以有效的保证在页面上写入JavaScript,而不会造成全局变量的污染问题。通过小括号,让其加载时立即初始化,这样就形成了一个单例模式的效果,从而只会执行一次。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息