简体   繁体   English

传递变量VS传递值

[英]Passing variables VS passing values

I would love to understand the difference between: 我很想了解以下两者之间的区别:

var the_timeout = setTimeout("alert(the_string);", 60000);

and: 和:

  var the_timeout = setTimeout("alert(" + the_string + ");",60000);

I understand that the first passes the variable, and the second passes the value - but what does that mean exactly and why does it matter? 我知道第一个传递变量,第二个传递值-但这到底是什么意思,为什么重要呢? Why is the value passed in the second example? 为什么在第二个示例中传递值?

Also (I hope this is the same subject), why does this work: 另外(我希望这是同一主题),为什么起作用:

var timeout=setTimeout("someFunction();", 3000)

While this doesn't: 虽然这不是:

var timeout=setTimeout(someFunction(),3000);

When calling a function, someFunction() works, so why do I have to add quotes when using setTimeout()? 调用函数时, someFunction()起作用,所以为什么在使用setTimeout()?时必须加引号setTimeout()?

I think you're confusing the distinction between pass-by-value and pass-by-reference with this. 我认为您与此混淆了“按值传递”和“按引用传递”之间的区别。 In the examples you mentioned, there is no difference. 在您提到的示例中,没有区别。

However, 然而,

var timeout=setTimeout("someFunction();", 3000)

Works and: 作品和:

var timeout=setTimeout(someFunction(),3000);

Doesn't because in the second case, someFunction() would run so that it can then pass the result/return value to setTimeout . 并不是因为在第二种情况下, someFunction()会运行,以便随后可以将结果/返回值传递给setTimeout That's why you pass it as a string so that setTimeout can eval it on its own. 这就是为什么将它作为字符串传递,以便setTimeout可以独立eval它的原因。 Unless, of course, if someFunction() itself returns a function that setTimeout can use as a callback. 除非,当然,除非someFunction()本身返回setTimeout可以用作回调的函数。

However, as zerkms pointed out in a comment, you should pass callbacks instead: 但是,正如zerkms在评论中指出的那样,您应该传递回调:

var timeout = setTimeout(function() { someFunction(); }, 3000);

This also has the effect that setTimeout can then call the callback whenever it wants. 这还具有以下效果: setTimeout然后可以在需要时调用回调。 A major benefit is that you can pass any regular function so that you can benefit from the editor you may be using, instead of packing it all into a string: 一个主要的好处是您可以传递任何常规函数,以便可以从可能使用的编辑器中受益,而不是将所有内容打包到一个字符串中:

var myTrigger = function() {
  someFunction();
};

var timeout = setTimeout(myTrigger, 3000);

This will parse execute the code within the string, 60 seconds later. 60秒后,它将解析执行字符串中的代码。

var the_string = "Hello";
setTimeout("alert(the_string);", 60000);
the_string = "Goodbye";

This means alert(the_string) is executed, just as if it was regular code. 这意味着将执行alert(the_string) ,就好像它是常规代码一样。 So it would alert "Goodbye". 因此它将提醒“再见”。 This is because when the code is eventually executed, the updated value of the_string is used since you are passing the variable. 这是因为最终执行代码时,因为要传递变量,所以将使用the_string的更新值。

But this does something subtly different. 但这确实有所不同。

var the_string = "Hello";
setTimeout("alert(" + the_string + ");",60000);
the_string = "Goodbye";

Now we are creating a new snippet of code on the fly. 现在,我们正在动态创建一个新的代码片段。 The snippet we are creating is alert(Hello); 我们正在创建的代码片段是alert(Hello); . But Hello is a variable with no value because you didn't get the quotes right. 但是Hello是一个没有值的变量,因为您没有正确使用引号。

But lets say you meant this: 但是可以说你的意思是这样的:

var the_string = "Hello";
setTimeout("alert('" + the_string + "');",60000);
the_string = "Goodbye";

Now this will work, because the code it generates is alert('Hello'); 现在这将起作用,因为它生成的代码是alert('Hello'); . Which at first glance appears to do the same thing. 乍一看似乎做同样的事情。 But because the generated code now includes literally a hardcoded string, so when the_string changes, the change doesn't make it into generated code because it was hardcoded into the snippet. 但是,因为现在生成的代码实际上包含一个硬编码的字符串,所以当the_string更改时,由于它已硬编码到摘录中,因此更改不会将其更改为生成的代码。

Based on that, this is simple: 基于此,这很简单:

setTimeout("someFunction();", 3000)

The code in the string is executed after the delay. 延迟后将执行字符串中的代码。 In this case, someFunction() is executed. 在这种情况下,将执行someFunction()

But this is totally different: 但这是完全不同的:

setTimeout(someFunction(),3000);

In this case, someFunction() is executed immediately , and it's return value is passed as the first argument to the setTimeout() function. 在这种情况下, someFunction()立即执行 ,并将其返回值作为第一个参数传递给setTimeout()函数。 So it won't do what you expect at all. 因此,它根本无法实现您的期望。


Most of this has to do with the quirks of eval and generated code, as setTimeout(string,delay) is a form of eval . 大多数情况与eval和生成的代码有关,因为setTimeout(string,delay)eval一种形式。 And none of this is a problem if you don't use eval , and you don't pass a string to setTimeout() . 如果您不使用eval ,并且不将字符串传递给setTimeout() ,那么这都不是问题。

Passing a string to setTimeout leads to eval , eval leads to wierd crazy bugs, wierd crazy bugs lead to pain, pain leads to sufferrriing . 将字符串传递给setTimeout会导致evaleval会导致怪异的疯狂bug,怪异的疯狂bug会导致痛苦,痛苦会导致痛苦

Instead you pass a function instead. 相反,您可以传递一个函数。 It's better in every single way. 每种方式都更好。

// pass an anonymous function to run some code later
var the_string = "Hello";
setTimeout(function() {
  alert(the_string);
}, 60000);
the_string = "Goodbye";
// alerts "Goodbye" 60 seconds later


// pass an anonymous function to run some code
setTimeout(function() {
  someFunction();
}, 3000);

// or pass a reference to a function to execute, note lack of ()
setTimeout(someFunction, 3000);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM