[英]Looking for some js scope hack
Here some interesting behaviour of javascript function arguments variable that you may be or maybe not aware of: 这里有一些你可能或可能不知道的javascript函数参数变量的有趣行为:
function foo(bar) {
console.log('bar was:', bar);
arguments[0] = 'zap';
console.log('bar now:', bar);
}
foo('bam');
// bar was: bam
// bar now: zap
As you can see bar
variable now pointing out to another value. 正如您所见,
bar
变量现在指向另一个值。
I want to make use of such behavior in a slightly strange way, I want to know is it possible to change argument value from the outside of the function scope somehow? 我想以一种稍微奇怪的方式利用这种行为,我想知道是否有可能以某种方式从函数范围的外部更改参数值?
Maybe using call/apply, or some other trycky js features? 也许使用call / apply或其他一些trycky js功能?
So I can change the value of function argument after it was called, for example: 所以我可以在调用后更改函数参数的值,例如:
function chooseNumber(number) {
setInterval(function() {
console.log('I choosed:', number)
}, 1000)
}
chooseNumber(1);
// I choosed: 1
// I choosed: 1
// I choosed: 1
// ...
Then if I dicided to change my mind, how can I make so that initial function would output: 然后,如果我决定改变主意,我怎样才能输出初始函数:
// I choosed: 2
// I choosed: 2
// I choosed: 2
// ...
No, it should not be possible especially not with EcmaScript 5 strict mode. 不,特别是在EcmaScript 5严格模式下不可能。 However hackery can succeed in non-strict mode.
然而,hackery可以在非严格模式下成功。 The following tries to modify arguments within a closure via a stored
arguments
object; 以下尝试通过存储的
arguments
对象修改闭包内的arguments
; works on Firefox. 适用于Firefox。
var argsave, bar;
(function foo(a) {
argsave = arguments;
bar = function () {
alert("a is now: " + a);
};
} (13));
bar(); // --> a is 13
argsave[0] = 42;
bar(); // --> a is 42
However you do not need it, and should not use it; 但是你不需要它,也不应该使用它; if you want to modify a value within a closure, then use a function within the closure:
如果要修改闭包内的值,则在闭包内使用函数:
var setA, bar;
(function foo(a) {
bar = function () {
alert("a is now: " + a);
};
setA = function (newA) {
a = newA;
};
} (13));
bar(); // --> a is 13
setA(42);
bar(); // --> a is 42
A better way is to clear previous interval and then register your setInterval again with new behaviour as follows. 更好的方法是清除先前的间隔,然后再次使用新行为注册setInterval,如下所示。
function chooseNumber(number) {
var int = setInterval(function() {
console.log('I choosed:', number)
}, 1000) ;
return int;
}
var interval = chooseNumber(10);
if(someCondition ){
clearInterval(interval);
interval = chooseNumber(20);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.