1. 立即执行函数
简化后的代码就是这样
(function(global, factory) {
...
})(window, function () {});
Q:采用立即执行函数的好处是什么呢?
A: 通过定义一个匿名函数,创建了一个新的函数作用域,相当于创建了一个私有的命名空间,不会污染全局变量。若想访问全局对象,将全局对象以参数的形式传进去即可。此外,新的作用域内对象想访问传入的全局对象时,就不需要一步一步的往上找,可提高效率。
2. init()
我们看如下一段代码:
var s = new $('.test');
var p = $('.test');
console.log(s);
console.log(p);
效果如下
令人惊讶的是,new 出来的和直接调用的,居然是一模一样的。
这就设计到了jQuery的经典的init操作:
查看core文件,可以了解到:
// 1
jQuery = function (selector, context) {
return new jQuery.fn.init(selector, context);
}
// 2
jQuery.fn = jQuery.prototype = {
init: function (selector, context ) {
...
}
}
// 3
init = jQuery.fn.init = function (selector, context, root) {
...
}
init.prototype = jQuery.fn;
- 步骤1: 我们从代码块2开始看,jQuery.prototype = jQuery.fn,且都挂在了init()函数。
- 步骤2: 代码块3,jQuery.fn.init.prototype = jQuery.fn,而我们从步骤1中,了解到jQuery.prototype = jQuery.fn。因此,jQuery.fn.init.prototype = jQuery.fn = jQuery.prototype。
- 步骤3: 最后,再回过头来看代码块1,function 返回的是 new jQuery.fn.init(...)。我们再看步骤2,jQuery.fn.init.prototype = jQuery.prototype。那么,new jQuery.fn.init(...)就相当于function 返回了一个new JQuery()。
绕了一大圈,就相当于 jQuery = new jQuery();
Q: 那么,为啥要绕那么远呢?
A: 为了得到jQuery原型链上的方法。