使用变量将函数表达式传递给新的Function()

时间:2013-02-16 07:26:07

标签: javascript function

这是有史以来最令人困惑的事情。标题可能没什么意义。我尽力了。希望我能说清楚。 好的,我正在看谷歌频道api的tic-tac-toe示例。

在javascript部分。

他们有类似的东西;

sendMessage = function(param) {
  alert(param);
  //this part actually sends message to server, 
  //for simplicity lets assume it pops up alert.    
  }

init = function(){
  var input = 3;
  var submitButton = document.getElementById('submitButton');
  submitButton.onclick = new Function('sendMessage(' + input + ')');
}

setTimeout(init, 100);

这会弹出警报并打印3.我不确定这是如何工作的。但它的确有效。如果可以解释一下,那也会很棒。我在其他地方找不到像这样的新功能()。

问题是,如果输入是字符串,

var input = "test";

这不起作用,并且没有弹出警报。

感谢您的任何解释和帮助。

3 个答案:

答案 0 :(得分:1)

Function构造函数通过eval将其参数作为函数体来工作。

... = new Function('sendMessage(' + input + ')');

类似于

... = eval("function(){sendMessage("+input+")}";

对于数字input,这是有效的,因为它们的文本表示作为数字文字。对于文本输入,它没有。通过

可以获得有限的支持
... = new Function('sendMessage("'+input+'")');

更通用的方法是使用

... = new Function('sendMessage("'+JSON.stringify(input)+'")');

但是,我建议使用立即调用的函数表达式(IIFE)来避免任何形式的eval以及对JSON对象的依赖,这在非常旧的浏览器中是不存在的(IE< 1> 8):

... = (function(input){
  return function(){
    sendMessage(input)
  }
})(input)

或者,如果input变量没有改变,则不需要捕获其值:

... = function(){ sendMessage(input) }

或者,如果您不在sendMessage中使用this,则可以使用bind(IE8需要填充):

... = sendMessage.bind(undefined, input)

答案 1 :(得分:0)

当输入是字符串时,函数调用变为:

sendMessage(string)

实际应该是:

sendMessage("string")sendMessage('string')

sendMessage = function(param) {
  alert(param);   
  }

init = function(){
  var input = '"string"';
  var submitButton = document.getElementById('submitButton');
  submitButton.onclick = new Function('sendMessage(' + input + ')');
}

setTimeout(init, 100);

以下是fiddle,了解您可以如何使用。

答案 2 :(得分:0)

要对函数的参数进行评估..也就是说它已被执行。这就是它起作用的原因。

当你传递一个字符串时它不起作用只是因为你传递的字符串将被视为一个对象或一个变量而不是一个字符串..我们都知道它不存在。

这有效:

submitButton.onclick = new Function('sendMessage(3)');

这不是:

submitButton.onclick = new Function('sendMessage(test)'); //because test does not exist

但这将

submitButton.onclick = new Function('sendMessage("test")');

所以,如果您将代码更改为:

submitButton.onclick = new Function('sendMessage("' + input + '")');

然后一切都很好