首先,我不确定这是使用此库的正确方式。我想在模块中定义多个函数/静态方法,并在模块的范围内使用它们。例如:
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()
代码中访问方法和属性?
答案 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来完成(此函数称为定义函数)。在定义函数内部:
使定义函数返回一个具有您希望模块公开的功能的对象。在这里,在您返回的对象中,您可以调用上一步中定义的函数。
define(function() {
function foo() {
return "Hello";
};
return {
bar: function() {
alert(foo());
}
}
});