2

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

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

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

主.js

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

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

});

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

4

3 回答 3

4

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

您可以通过使用函数来拥有内部范围。您可能希望像这样声明您的模块:

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

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

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


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

问题实际上出在 中main.js,而不是在您的模块中。问题是 JS 如何处理this. 这大多数其他语言不同!this在 JS 中是调用函数的上下文,而不是定义函数的上下文。您可以apply对其他对象起作用,即使它们没有此功能。

在你的情况下,你想要bind bar你的foobar对象,所以thisinbar是正确的对象。您bind为此使用该功能。它创建一个新函数,其上下文设置为您指定的对象。例子:

function doubleMe () { return this * 2; }

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

doubleMe.apply(5) // returns 10

你也可以这样做:

var giveMeTen = doubleMe.bind(5);

NowgiveMeTen是一个函数,10如果执行则返回。我鼓励您阅读有关此主题的更多信息,this起初的处理很奇怪,但如果理解则很漂亮;-)


关于你的代码,我会写:

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

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

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

于 2013-08-29T19:08:34.577 回答
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());
} 

希望这可以帮助。(您可能会猜到如何使用封闭范围从中制作单例)

于 2013-08-29T18:20:09.410 回答
2

这可以通过传递一个函数来定义来完成(这个函数称为定义函数)。定义函数内部:

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

    define(function() {
        function foo() {
            return "Hello";
        };
    
        return {
            bar: function() {
                alert(foo());
            }
        }
    });
    
于 2014-12-07T10:35:39.160 回答