RequireJS模块中的自引用

时间:2013-08-29 17:57:57

标签: javascript requirejs

首先,我不确定这是使用此库的正确方式。我想在模块中定义多个函数/静态方法,并在模块的范围内使用它们。例如:

define({
        foo: function() {
            return "Hello";
        },

        bar: function() {
            alert( this.foo() );
        }
});

Main.js

require( ['foobar'], function( foobar) {

        foobar.bar(); // works
        $('body').click( foobar.bar ); // crash - Object #<HTMLBodyElement> has no method 'foo' 

});

如果事件触发bar(),则此代码无效,因为显然this在该范围内意味着不同。是否有任何全局变量引用已定义的对象,并允许我从define()代码中访问方法和属性?

3 个答案:

答案 0 :(得分:4)

编辑:有关this的信息,请参阅下文。

您可以使用函数来拥有内部范围。您可能想要声明您的模块:

define((function () { var self = {   // this line is changed
        foo: function() {
            return "Hello";
        },

        bar: function() {
            alert( self.foo() );
        }
}; return self; }()));    // and this

我承认,这看起来很糟糕。点是,它存储对您返回的对象的引用,并使用它来调用foo。我不确定你是否希望它像这样...但它确实有用。


注意:这部分是关于JS中this的处理。请参阅评论为什么这个问题与此问题不再相关。

问题实际上在main.js,而不在您的模块中。问题是JS处理this的方式。这与大多数其他语言相同! JS中的this是函数被称为的上下文,而不是定义的。即使没有这些功能,你也可以apply对其他对象起作用。

在您的情况下,您希望bind bar添加到foobar对象,因此this中的bar是正确的对象。您可以使用函数bind。它创建一个新函数,并将上下文设置为您指定的对象。例如:

function doubleMe () { return this * 2; }

您可以通过执行以下操作来调用此函数:

doubleMe.apply(5) // returns 10

你也可以这样做:

var giveMeTen = doubleMe.bind(5);

现在giveMeTen是一个函数,如果执行则返回10。我鼓励你阅读更多有关这个主题的内容,this的处理起初很奇怪,但如果理解则很漂亮; - )


关于你的代码,我会写:

require( ['foobar'], function( foobar) {

        foobar.bar();
        $('body').click( foobar.bar.bind(foobar));
});

请注意,jQuery将this设置为click()处理程序中单击的元素。

答案 1 :(得分:2)

不确定你要在这里完成什么,或许你想要做更多的背景,我们可以给你更准确的咨询。

尽管如此,我通常使用requireJS(主要是类)来创建模块

if ( typeof define === "function" && define.amd ) {
    define( "module", function () {
        var MyModule = function(){
            this.foo = function(){
                return "Hello!";
            };
            this.bar = function(){
                return this.foo();
            };
         }

         return MyModule;
     });
}

现在使用:

require("module", function(MyMod){
    var a = new MyMod();
    console.log(a.bar());
} 

希望这会有所帮助。 (你可以猜测如何使用封闭的范围来制作单身人士)

答案 2 :(得分:2)

这可以通过将函数传递给define来完成(此函数称为定义函数)。在定义函数内部:

  1. 定义您要在模块中使用的功能。
  2. 使定义函数返回一个具有您希望模块公开的功能的对象。在这里,在您返回的对象中,您可以调用上一步中定义的函数。

    define(function() {
        function foo() {
            return "Hello";
        };
    
        return {
            bar: function() {
                alert(foo());
            }
        }
    });