使variables可用于不带闭包的asynchronous调用

我是一个初学者的JavaScript。 我试图找出一种方法来解决嵌套函数。 看看下面的两个例子

// example 1 var x = 45; function apple(){ var y = 60; setTimeout(function(){ console.log(y); console.log(x); }, 20); } apple(); console.log(x); 

那么值y保持不变,并将其打印在控制台上,因为setTimeout与函数apple()形成closures,并且工作良好。 现在看看下面的代码

 var x = 45; var run = function(){ console.log(y); console.log(x); }; function apple(){ var y = 60; setTimeout(run, 20); } apple(); console.log(x); 

我只是想单独放置函数体,并将函数处理函数作为parameter passing,但我坚持的是我如何使函数的variablesapple()可用于函数run()因为它们不再形成闭包。 有没有一个解决方法,使之成为可能? 请帮助我。

请以通用的方式回答我,以便它也适用于nodejs API。 我已经看到setTimeout接受更多的参数,但我希望解决scheme适用于函数原型而不考虑。

更新

对不起,但我认为所有的答案使用值传递进行函数调用。 它没有实现封闭。 它们取当前的y值并将其作为函数parameter passing,并假设在setTimeout()之后存在y = 80的语句,如下面的代码

 var y = 60; setTimeout(run, 20); y = 80; 

它打印y = 60而不是80内部run() 。 我实际上想要保持y的参照,而不是像closures那样捕获它的价值。 谢谢

你可以使用bind :

 var x = 45; var run = function(y){ console.log(y); console.log(x); }; function apple(){ var y = 60; setTimeout(run.bind(null, y), 20); } apple(); console.log(x); 

绑定的第一个参数是你想绑定到this 。 之后,每个parameter passing给新创build的函数 – 注意我将y作为参数添加到run函数中。

bind给你的是一个带有预定义上下文( this )的新函数,也可能是参数的默认值。

但请注意,你应该总是避免这样的情况。 修改函数内部的外部variables绝不是一个好主意,它会导致很多的悲伤和过早的灰色。 您应该尝试重构代码,以便可以传递和返回值,而不依赖于引用或全局范围的variables。

你的yvariables不在run()的范围内,所以你需要传递它来run 。 你也可以将run作为参数传给apple(cb_fn) https://jsfiddle.net/stevenkaspar/ttxxpoof/

 var x = 45; var y = 80; var run = function(){ console.log('could be 80 or 85(depending on race condition): ' + y); console.log('should be 45: ' + x); }; function apple(cb_fn){ var y = 60; // you can declar var y again to have another ignore global y setTimeout(function(){ console.log('should be 60: ' + y); cb_fn(); // this would be a callback function }, 20); } apple(run); // you need to pass run in as a "callback" function console.log('should be 45: ' + x); y = 85; console.log('should be 85: ' + y); 

你可以用y来做和你一样的x(把它设置为全局)。