jQuery原型和构造函数链接

时间:2013-03-09 04:44:08

标签: javascript jquery object prototype

jQuery如何允许其构造函数作为接受参数的函数,同时它的构造函数还充当接受参数的函数?

我对JavaScript有点新手,如果这是一个noob问题,请原谅我(我已经查看了源码,但很难尝试剖析)。

无论如何,作为示例$(document).ready(<args>);构造函数$()和原型ready()都充当函数。怎么样?因为如果我试试这个:

var $ = function( selector ) {
    if(selector == document) {
        return document;
    }
};

$.prototype = {
    constructor: $,
    ready: function( args ) {
        if( isDomReady ) {
            args.apply( document );
        } else {
            window.onload = args;
        }
    }
};

var isDomReady = ( document.addEventListener || document.readyState == ("complete"|"loaded"|true|4) || document.onreadystatechange() ) ? true : false;

$(document).ready(function() { alert("Wibbles!") });

我收到错误未捕获TypeError:对象[object global]没有方法'ready'

2 个答案:

答案 0 :(得分:8)

你知道,这引起了我的兴趣。你已经接受了一个答案,但是如果事实证明它有用的话,请让我发帖。有一个fiddle created here

jQuery = function( selector, context ) {
    // The jQuery object is actually just the init constructor 'enhanced'
    return new jQuery.fn.init( selector, context );
};

jQuery.fn = jQuery.prototype = {
    constructor: jQuery,
    context: null,
    isReady: null,
    init: function( selector, context ) {
        if (selector === document){
            this.context = document;
            this.selector = document;
        }
        console.log(this);
        return this;
    },
    ready: function(func){
        var args = Array.prototype.slice.call(this, arguments),
            boundReadyFunc = func.bind(this, args.slice(1));

        if (this.isReady){
            func();
        }
        else {
            document.addEventListener( "DOMContentLoaded", this.onReady.bind(this, func), false );
        }
    },
    onReady: function(func){
        console.log("onready");
        this.isReady = true;
        func.call(this);
    },
};

jQuery.fn.init.prototype = jQuery.fn;
jQuery(document).ready(function(){
    alert("Hey, here I am");
});

让我试着解释一下这是如何运作的。

每次调用类似$(selector)的内容时,都会创建一个新的jQuery实例,其中包含您提供的选项(请参阅return new jQuery.fn.init( selector, context ););

为方便起见,我们将jQuery原型公开为另一个名为jQuery.fn的全局。为了使其真正可链接,init函数必须返回一个新的jQuery实例。这就是为什么最后我们明确定义jQueryjQuery.init的原型是相同的。这样,您现在可以链接函数调用,如

$(document).ready(DoSomethingHere)

希望这有帮助。

此外,您可以在github上找到jQuery源代码。它是模块化的,很容易理解。

答案 1 :(得分:2)

这是一种称为函数链的编程技术。

您可以在此处查看更多内容:How does basic object/function chaining work in javascript?