寻找一些js范围的黑客

时间:2013-08-17 15:17:08

标签: javascript scope

这里有一些你可能或可能不知道的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

正如您所见,bar变量现在指向另一个值。

我想以一种稍微奇怪的方式使用这种行为,我想知道是否有可能以某种方式从函数范围外部更改参数值?

可能使用call / apply或其他一些trycky js功能?

所以我可以在调用后更改函数参数的值,例如:

function chooseNumber(number) { 
    setInterval(function() { 
        console.log('I choosed:', number) 
    }, 1000) 
}

chooseNumber(1);
// I choosed: 1
// I choosed: 1
// I choosed: 1
// ...

然后,如果我决定改变主意,我怎样才能输出初始函数:

// I choosed: 2
// I choosed: 2
// I choosed: 2
// ...

2 个答案:

答案 0 :(得分:4)

不,特别是不能使用EcmaScript 5严格模式。然而,hackery可以在非严格模式下成功。以下尝试通过存储的arguments对象修改闭包内的参数;适用于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

但是你不需要它,也不应该使用它;如果要修改闭包内的值,则使用闭包内的函数:

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

答案 1 :(得分:0)

更好的方法是清除上一个间隔,然后再次使用新行为注册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);

}