8

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

我对 JavaScript 有点陌生,所以如果这是一个菜鸟问题,请原谅,(我已经查看了源代码,但很难尝试剖析)。

无论如何,作为示例$(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!") });

我收到一个错误Uncaught TypeError: Object[object global] has no method 'ready'

4

2 回答 2

8

你知道,这让我很感兴趣。你已经接受了一个答案,但如果它证明有用,让我发布我的答案。这里创建了一个小提琴

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 源代码。它是模块化的,很容易遵循。

于 2013-03-09T05:35:53.367 回答
2

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

您可以在此处查看更多信息:基本对象/函数链接如何在 javascript 中工作?

于 2013-03-09T05:03:02.937 回答