简体   繁体   English

JavaScript setTime()与回调VS. 具有匿名功能

[英]JavaScript setTime() with Call back VS. with anonymous function

I found the following two examples of setTime function, although the code looks the same, the result is different in the two cases. 我找到了以下两个setTime函数的例子,虽然代码看起来相同,但结果在两种情况下是不同的。

Example1: Result "Hello Stack Overflow" 示例1:结果“Hello堆栈溢出”

var a = "world";  
setTimeout(function(){alert("Hello " + a)}, 2000);  
a = "Stack Overflow";    

Example2: Result "Hello world" 示例2:结果“Hello world”

function callback(a){  
    return function(){  
        alert("Hello " + a);  
    }  
}  
var a = "world";    
setTimeout(callback(a), 2000);    
a = "Stack Overflow";    

Why in the first example the value of a changed, and in excample2 it didn't? 为什么在第一个例子中a的值发生了变化,而在excample2中它没有?

In the first example, the function reads the value of a directly. 在第一个例子中,函数读取的值a直接。 In the second example, the function reads the value of the parameter passed to it's factory function. 在第二个示例中,函数读取传递给它的工厂函数的参数的值。 Even though we reassign the value of the variable later, that doesn't affect the value of the parameter. 即使我们稍后重新分配变量的值,也不会影响参数的值。 It might be more clear if a different name is used for the parameter: 如果参数使用不同的名称可能会更清楚:

function callback(x){  
    return function(){  
        alert("Hello " + x);  
    }  
}  
var a = "world";    
setTimeout(callback(a), 2000);    
a = "Stack Overflow";

If you had used an object, you'd have a different story. 如果您使用过一个物体,那么您将拥有不同的故事。 Modifying your examples slightly, these both have the same result: 稍微修改您的示例,这些都具有相同的结果:

Example 1 例1

var o = {};
o.a = "world";
setTimeout(function(){alert("Hello " + o.a)}, 2000);  
o.a = "Stack Overflow";

Example 2 例2

function callback(obj){  
    return function(){  
        alert("Hello " + obj.a);  
    }  
} 
var o = {};
o.a = "world";
setTimeout(callback(o), 2000);    
o.a = "Stack Overflow";    

It doesn't change in the second example because you are actually creating a new local variable a as the argument to the callback function. 它在第二个示例中没有改变,因为您实际上是在创建一个新的局部变量a作为callback函数的参数。 So when you change the value of the global a it doesn't effect the value of the a inside that function. 所以,当你改变全局的价值a它不会影响价值a该函数内部。

  • global var a points at the string "world" 全局变量a在字符串“世界”点
  • global var a gets passed to function 全局变量a被传递给函数
  • local var a is created and set to the value of global var a 创建局部变量a并将其设置为全局变量a的值
  • global var a is set to a new value global var a设置为新值
  • function later runs, and uses the value of local var a 函数稍后运行,并使用local var a的值

So because function arguments have the semantics of local variables, you can't change it after the fact like this. 因为函数参数具有局部变量的语义,所以在这样的事实之后你不能改变它。

In your second example callback(a) creates a closure which maintains the current value of a so when it executes after the specified timeout you see the old value. 在你的第二个例子中callback(a)创建一个封闭其保持的当前值a当你看到旧值指定的超时后执行如此。

You should read this JavaScript Closure 你应该阅读这个JavaScript Closure

通过调用callback函数, a的初始值被复制(通过值传递),返回的函数形成一个闭包,这就是它显示初始值而不是最新值的原因。

第二个没有按预期工作,因为你正在调用函数 ,这使它立即执行,而不是传递给setTimeout,它将在指定的时间后执行。

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

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