2014-12-02 82 views
1

考虑这段JavaScript代码:应用动态参数的JavaScript功能,但推迟调用

var someArg = "Hello"; 
elem1.onclick = function() { foo(someArg); }; 
someArg = "Bye"; 
elem2.onclick = function() { foo(someArg); }; 

我想调用FOO的说法“你好”当我点击elem1,但是,上面的代码工作的方式, foo每次调用“Bye”。

基本上,我想申请someArg为foo但不实际调用FOO,直到后来。

回答

3

你做到这一点,通常的方法是使用生成器功能:

var someArg = "Hello"; 
elem1.onclick = buildHandler(someArg); 
someArg = "Bye"; 
elem2.onclick = buildHandler(someArg); 

function buildHandler(arg) { 
    return function() { foo(arg); };; 
} 

...或Function#bind

var someArg = "Hello"; 
elem1.onclick = foo.bind(null, someArg); 
someArg = "Bye"; 
elem2.onclick = foo.bind(null, someArg); 

无论哪种方式,你正在做的是创造一个新的功能是什么那么在拨打电话时,请拨打foo,并将的值传递给您。您的原始代码不起作用的原因是这些函数关闭了变量someArg,而不是它们创建时的值。所以,因为他们在被调用时使用了这个值,所以你没有得到你想要的值。上述两种解决方案(以不同的方式)都创建了一些函数,它们可以在创建函数时关闭某些值,而不是创建函数。

+0

如果您使用的是UnderscoreJS或Lodash,则执行相同操作的另一种方法是使用'_.partial()'。 – GregL 2014-12-02 01:52:11

+0

@GregL:或PrototypeJS的'咖喱',但该列表可能会很快... – 2014-12-02 01:53:02

+0

非常感谢,这正是我所期待的。也许我应该在OP中提到,我知道问题是什么,为什么会发生,我只是在寻找解决方案,但感谢您再次解释。 – 2014-12-02 02:10:52

0

这是因为,这是Javascript的工作原理。你将不得不用不同的变量调用foo()来达到这个目的。我只看到一个办法解决这个..

var someArg1 = "Hello"; 
var someArg2 = "Bye"; 
elem1.onclick = function() { foo(someArg1); }; 
elem2.onclick = function() { foo(someArg2); }; 

这是因为,只有当你调用foo() foo将得到的参数和参数将是可变someArg在调用该点的值。而且由于Javascript在页面加载时执行函数调用之外的所有内容,因此它在页面加载时也会执行someArg = 'Bye'

0

你有它设置,JavaScript是几乎立即就首先定义它后更改负载someArg的定义方式。你需要使用像这样的另一个变量:

var someArg = "Hello"; 
elem1.onclick = function() { foo(someArg); }; 
var someArg2 = "Bye"; 
elem2.onclick = function() { foo(someArg2); }; 

或变量传递到函数,并定义变量别处:

elem1.onclick = function(someArg) { foo(someArg); }; 
elem2.onclick = function(someArg) { foo(someArg); }; 
//Some stuff happens.... 
thisVariable = 'stuff happened'; 
elem2.onclick(thisVariable); 

这将导致FOO被称为用“的东西发生了”论据。

希望这会有所帮助。如果没有,请提供关于您的用例的更多细节,以便我们可以更多地集中我们的答案。

+0

这并不能解决我的问题,因为在我的情况下,someArg是一个循环变量,它会改变未知次数,所以我不能只为不同的赋值使用不同的变量名称。 但是,您的文章可能会说明为什么我的代码不适用于不知道的人。 – 2014-12-02 02:04:10