我是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()
的闭包,并且效果很好。现在看一下下面的代码
var x = 45;
var run = function(){
console.log(y);
console.log(x);
};
function apple(){
var y = 60;
setTimeout(run, 20);
}
apple();
console.log(x);
我只是想单独放置函数体并将函数处理程序作为参数传递,但我坚持的事情是如何使函数apple()
的变量可用于函数run()
,因为它们可以不再形成封闭。是否有解决方法使其成为可能?请帮助我。
请以通用方式回答我,以便它也适用于nodejs API。我已经看到setTimeout
接受了更多的参数,但我希望解决方案适用,而不管函数原型如何。
更新
很抱歉,但我认为所有答案都是使用pass by value进行函数调用。它没有实现关闭。它们获取当前y
值并将其作为函数参数传递,并假设y = 80
之后的setTimeout()
语句如下面的代码
var y = 60;
setTimeout(run, 20);
y = 80;
打印y = 60而不是run()
内的80。我实际上想要保持y的引用而不是像闭包那样捕获它的值。谢谢
答案 0 :(得分:2)
您可以使用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);
bind的第一个参数是你想要绑定到this
的东西。之后,每个参数都传递给新创建的函数 - 请注意我将y
作为参数添加到run
函数。
bind
给你的是一个带有预定义上下文(this
)的新函数,可能还有参数的默认值。
请注意,您应该始终避免这样的情况。修改函数内部的外部变量绝不是一个好主意,它会导致很多悲伤并过早地变灰。您应该尝试重构代码,以便传递和返回值,而不是依赖引用或全局范围的变量。
答案 1 :(得分:0)
您的y
变量不在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);
答案 2 :(得分:0)
您可以使用与x相同的方法(将其设置为全局)。