jQuery源码笔记.jpg

jQuery源码二周目#1 整体架构

2020-07-21  本文已影响0人  柠檬果然酸

jQuery无new构建

首先说说$()是个什么东西,它其实就是一个方法(因为js中可以用$命名),它等价于jQuery()
所有声明的全局变量都是挂载在window下的,也就是说可以通过window.$达到调用jQuery的效果。
然后就说道jQuery的无new构建,怎么才能做到调用一次方法创建一个对象,答案如下:

var jQuery = function(selector, context) {
    return new jQuery();
}

很可惜上面的答案是错的,这样会导致死循环,无限的自己创建自己。不过和真正的答案很接近了。正确代码如下:

var jQuery = function(selector, context) {
    return new jQuery.fn.init();
}

jQuery.fn = jQuery.prototype = {
    
    init: function() {
        
    }
}

这样就不会出现死循环。然后jQuery的整体思路是通过$()创建一个新的jQuery对象,jQuery的所有方法写在原型中,这样所有的对象都能够共用原型方法,节省内存开支。

jQuery.fn = jQuery.prototype = {

    init: function() {

    },
    
    method1: function () {}, // 方法1
    method2: function () {}, // 方法2
    // 更多方法...
}

我们预想的是通过$()创建一个jQuery对象,然后对象中有着method1()method2()等等方法,但是实际上你会发现里面空空如也,因为我们创建的是jQuery.fn.init对象而非jQuery对象。这个问题也好解决,就是通过简单的一行jQuery.fn.init.prototype = jQuery.fn;搞定。

原型小知识点:如果在对象没有找到目标属性,就去对象的原型中去查找。上代码有助于理解:

function fn() {

}

fn.prototype = {
    name: '柠檬'
}

var fn1 = new fn();
console.log(fn1.name); // 柠檬

整体结构

(function(window, undefined) {
    
    var jQuery = function(selector, context) {
        return new jQuery.fn.init(selector, context, rootjQuery);
    }
        
    jQuery.fn = jQuery.prototype = {
        init: function(selector, context, rootjQuery) {

        }
    }

    jQuery.fn.init.prototype = jQuery.fn;

})(window);

整个结构用一个即时函数包裹整个jQuery源码,这样能够保证jQuery内定义的属性不会对我们造成影响。即时函数传入了一个window对象,其目的是将$jQuery挂载在window下作为全局函数。

jQuery第一步就完成了,第一步还是挺简单,到了后面诸位就会明白读懂源码是多么难的一件事,这需要耐心,为什么这么说,因为一段代码你可能前99次都看不懂。当然真实的情况不会这么夸张,以我的经验最多几十遍就懂了。

上一篇下一篇

猜你喜欢

热点阅读