乐趣区

Jquery和zepto中的原型应用及插件机制

zepto 实现

var Zepto = (function(){var zepto = {}
    // 构造函数
    function Z(dom, selector){
        var i, len = dom ? dom.length : 0
        for(i = 0; i < len; i++) this[i] = dom[i]
        this.length = len
        this.selector = selector || ''
    }
    zepto.Z = function(){return new Z(dom, selector)
    }
    
    //init 函数,判断传入的 selector,并分情况对 dom 赋值:zepto.init = function(selector, context){
        var dom
        // 如果是字符串,返回 dom 节点对象的数组
        var slice = Array.prototype.slice;
        dom = slice.call(document.querySelectorAll(selector))
        return zepto.Z(dom, selector)
    }
    
    // 入口,定义 $ 操作符,$('div')
    var $
    // ...
    $ = function(selector, context){return zepto.init(selector, context)
    }
    // ... 省略 N 行代码...
    $.fn = {
        constructor: zepto.Z,
        css: function (key, value) {// ...},
        html: function (value) {// ...}
    zepto.Z.prototype =  Z.prototype = $.fn
    // 构造函数 Z 的原型的方法,是在 $.fn 定义完了之后,又赋值给 Z.prototype 的
    return $
})()

window.Zepto = Zepto
window.$ === undefined && (window.$ = Zepto)

zepto 中,通过 ’$()’ 入口函数,返回 init 函数,init 函数对 ’selector’ 进行判断,然后根据情况给 dom 变量赋值;最后到构造函数 Z 中,返回一个对象数组(可以模拟进行数组操作的对象),每一项定义为 dom 数组中的节点对象。构造函数的原型赋值给 Z.prototype。

Jquery 原型实现

(function(window){var JQuery = function(selector){return new JQuery.fn.init(selector)
    }
    JQuery.fn = {}
    // 定义构造函数
    var init = JQuery.fn.init = function (selector) {
        // ...
        var slice = Array.prototype.slice
        var dom = slice.call(document.querySelectorAll(selector))

        var i, len = dom ? dom.length : 0
        for (i = 0; i < len; i++) this[i] = dom[i]
        this.length = len
        this.selector = selector || ''
    }
    // 初始化 JQuery.fn
    JQuery.fn = JQuery.prototype = {
        constructor: JQuery,

        // 其他函数...
        css: function (key, value) {// ...},
        html: function (value) {// ...}
    }
    // 定义原型
    init.prototype = JQuery.fn;
    
    window.$ = JQuery
})(window)

jQuery 中,构造函数在定义为 JQuery.fn.init,其原型先定义为 JQuery.fn 对象,然后再进行赋值。最后通过入口函数 JQuery 返回对象。
通过 JQuery.fn 扩展插件,只有 JQuery 暴露在全局变量中,不能通过 init.prototype 直接扩展,且将插件扩展统一到 JQuery.fn.extend 接口,方便使用。

无论 zepto 还是 jQuery,都只暴露一个方法(zepto 或者 jQuery 方法)在全局变量中,所以扩展插件只能通过 $.fn,不能直接在构造函数的原型上进行扩展。

退出移动版