1

ここで、あなたが気付いているかもしれないし、気付いていないかもしれない 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変数は別の値を指しています。

そういう振る舞いをちょっと変わった形で利用したいのですが、どうにかして関数スコープ外から引数の値を変更できないか知りたいです。

呼び出し/適用、またはその他のトリッキーな 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
// ...
4

2 に答える 2

4

いいえ、特に EcmaScript 5 の厳格モードでは不可能です。ただし、ハッカーは非厳密モードで成功する可能性があります。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
于 2013-08-17T15:19:16.940 に答える
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);

}
于 2013-08-17T15:22:58.960 に答える