jquery源码之总体架构分析

jquery的总体代码架构简化以下:jquery

(function( window, undefined ) {
    //...定义各类变量
    jQuery = function( selector, context ) {
        return new jQuery.fn.init( selector, context, rootjQuery );
    },
    jQuery.fn = jQuery.prototype = {
        constructor: jQuery,
        init: function( selector, context, rootjQuery ) {},
        ...
    };
    jQuery.fn.init.prototype = jQuery.fn;
    if ( typeof window === "object" && typeof window.document === "object" ) {
        window.jQuery = window.$ = jQuery;
    }
})( window );

这里有几点须要整明白的:
一、使用一个闭包定义jquery,建立一个私有空间,这样内外部的命名空间就不会相互干扰了。为了在外部可以使用jquery,将jquery($)提高到window做用域下,即:chrome

window.jQuery = window.$ = jQuery;

二、为何要将window做为参数传入:
有两个好处,一是便于代码压缩,jquery每一个版本都有压缩版,如将传入的window参数命名为w,则可减小大量的代码量;二是将window全局变量变成局部变量,可加快访问速度。浏览器

三、为何要增长undefined参数:
undefined在某些浏览器(如chrome、ie等)是能够被修改的,如:闭包

undefined = "hello";

为了保证在jQuery内部,使用到的undefined真的是undefined而没有被修改过,将它做为参数传入。
ok,上面几点都比较好理解,下面开始分析jquery的构建方式。
jQuery至关于一个类,在jquery中,咱们使用$()或jQuery()来获得jquery实例,按此思路定义jQuery类以下:架构

var jQuery = function() {
    return new jQuery();
}

啊噢,死循环了~
想拿到实例,即this,原方法拿不到,就去原型那里拿咯:this

var jQuery = function() {
    return jQuery.prototype.init();
}
jQuery.prototype = {
    init:function() {
        return this;
    }
}

但这样仍是会有问题,由于这样至关于单例了,建立出来的对象相互共享做用域,必然致使不少问题,如prototype

var jQuery = function() {
    return jQuery.prototype.init();
}
jQuery.prototype = {
    init:function() {
        return this;
    },
    age:18
}
var jq1 = new jQuery();
var jq2 = new jQuery();
jq1.age = 20;
console.log(jq1.age); //20
console.log(jq2.age); //20

因此须要让他们的做用域分离,互不干扰,故每次建立新对象便可解决:code

var jQuery = function() {
    return new jQuery.prototype.init();
}
jQuery.prototype = {
    init:function() {
        return this;
    }
}

可是这样仍然是有问题的,如:对象

var jQuery = function() {
    return new jQuery.prototype.init();
}
jQuery.prototype = {
    init:function() {
        return this;
    },
    age:18
}
var jq = new jQuery();
console.log(jq.age); //undefined

缘由是这里init和外部的jquery.prototype分离了,init对象中并无age属性。
改改改:作用域

var jQuery = function() {
    return new jQuery.prototype.init();
}
jQuery.prototype = {
    init:function() {
        return this;
    },
    age:18
}
jQuery.prototype.init.prototype = jQuery.prototype;

好了,到此为止基本没啥问题了,jQuery也是这样实现的,只是多了个jQuery.fn做为jQuery.prototype的引用而已,没多少特别意义。

相关文章
相关标签/搜索