一.1-前言

本次分析的jQuery源码版本是2.0.3

 

目录

1. jQuery 介绍

2. 如何只暴露出jQuery,$接口?

3. 接口jQuery(简写$)是怎么实现如此复杂的功能的?

4. extend--jQuery扩展功能的机制

 
 
 

1. jQuery 介绍

jquery是使用js编写的第三方库。按着官网的宣传,jQuery的优点是 write less,do more。

简而言之,js原生可能需要好几行才能实现的效果(还得考虑浏览器兼容问题),jquery可能一行代码就搞定了。(无需考虑兼容问题)

 
 
 

2. 如何只暴露出jQuery,$接口?

这个比较简单,我们通过立即执行函数,便可以将我们需要暴露的接口赋值给window即可

;(function(){ 
    function foo(){ 
        console.log(a); 
    } 
    window.a = 1; 
})(); 

console.log(a); // 1 
console.log(foo); // ReferrenceError

通过这样,我们便可以防止全局作用域被污染,又可以暴露出接口供用户使用

 

但jQuery的写法有些不太一样, 如下所示

(function(e, undefined){
    function foo(){
        console.log(a);
    }
    window.a = 1;
})(window);

首先传入window对象的作用如下

  • 可以缩短作用域链(js标识符解析的效率并不是太高)

  • 便于代码压缩(变量e肯定比window短)

 

传入undefined的原因是

  • 早期浏览器的undefined竟然是可以被修改的

undefined = 1; 
console.log(undefined); // 返回1,undefined被修改

如果undefined一不小心被修改了,那么可能后面的程序会出错。

现在的浏览器是不能修改undefined了(修改了也无效),而且在严格模式下还会报错。

 

需要注意的是,这个版本的jQuery支持Amd规范。

 
 
 

3. 接口jQuery(简写$)是怎么实现如此复杂的功能的?

如下所示

$("ul li").css("background", "red");

$.extend({
    utilMethod: function(){
        console.log("utilMethod");
    }
})

显而易见,jQuery 是一个函数,在js中一切皆对象(《你不知道的js》有不同的看法)。既然是对象,当然可以添加方法了。

 

有一个问题是,这个jQuery函数竟然不new就可以返回对象了

我们确实通过工厂函数来批量造函数(这样就可以不用new),但是jQuery应该不会这样做。原因如下:

首先造出来的对象都叫Object,其次一些公共的方法每次都需要拷贝一下,非常消耗性能(jQuery的方法还特别多)

 

其实啊,jQuery这个函数其实new了构造函数了,不过是在内部帮我们new了。

// 源码61行,做了一定的修改
function jQuery(){
    // 源码中是new jQuery.fn.init(), 在96行的代码中可以看到其实jQuery.fn === jQuery.prototype
    // 这里也是简写,毕竟fn比prototype短了很多
    return new jQuery.prototype.init();
}

 

这里可以看出来,实际上jQuery new的构造函数在jQuery.prototype.init上。

function jQuery(){
    return new jQuery.prototype.init();
}

jQuery.prototype = {
    constructor: jQuery,
    init: function(){},
    eq: function(){}
}

这样的话,就会产生一个问题

问题是: new出来的构造函数的__proto__的指向是 jQuery.prototype.init.prototype。

但是我们需要使用jQuery.prototype上的方法。如下:

$("ul li").eq(0);
 
 

那该怎么办?

我们需要手动将 jQuery.prototype.init.prototype 重新赋值为 jQuery.prototype就可以了(毕竟__proto__只是一个引用)

// 源码283行,fn其实是prototype的缩写 
jQuery.fn.init.prototype = jQuery.fn;
 
 

4. extend,jQuery扩展方法的机制

难道jQuery的方法都是直接往jQuery.prototype上面写,这样的话,书写起来也不方便。

而且用户如果想要扩展jQuery方法的话,还得自己在jQuery.prototype上添加。

 

因此jQuery提供了extend方法,不但jQuery内部使用extend方法来实现其它功能,我们自己也可以使用extend来扩展jQuery的方法

这样的话,就不需要直接在jQuery.prototype上直接书写方法了。

 

下一篇说一下extend方法的实现

 
 
 

相关推荐