-2
function addLinks () {
   for (var i=0, link; i<5; i++) {
         link = document.createElement("a");
         link.innerHTML = "Link " + i;
         link.onclick = function (num) {
             return function () {
                 alert(num);
             };
         }(i);
}}

リンクごとにクロージャが作成されます。各クロージャーは、それが作成されたスコープへの参照を持っています。numループごとに引数が更新されているためclick、最初のリンクでアラートが発生するはず4です。ではない?

4

2 に答える 2

1

いいえ。

そして、あなたはいくつかのことを混乱させているからです:

  1. 関数の引数は関数に対してローカルです (大きな「unless」を持ち、番号 2 に保存され
    ます) オブジェクト (配列/関数を含む) または値を関数のスコープにエイリアスすることを目的としています。
    目標は、外部コードから引数として何を渡すかに関係なく、内部コードを意味のあるものにするために、パラメーターの名前を好きな名前に変更できるようにすることです。
    これは範囲とは関係ありません。

  2. JS の変数は、オブジェクトの場合は参照によって渡され、スカラーの場合は値によって渡されます。新しいクロージャ
    に渡すことの要点は、への参照ではなく、のが引数として渡されることです。これは、クロージャを含め ない場合に発生します。iii

オブジェクトを渡す場合、そのオブジェクトがi( obj.i += 1) を持っていた場合、クロージャであろうとなかろうと、各関数は の同じ値を指しますi。なぜなら、それらはすべて同じオブジェクトへの同じ参照を共有するからです。 .

オブジェクト参照によって渡され、スカラーはによって渡されます。技術的
には文字列オブジェクトと数値オブジェクトがありますが、それらを直接オブジェクト指向で処理しなければ、すぐにスカラー値に変換されます。

var i = 3,
    say_i = function () { console.log(i); };

var i = 3,
    say_i = (function (val) { return function () { console.log(val); }(i));

最初のものはへの参照を与えiます。
が実行されると、リアルタイム say_iで の値を確認し、それをコンソールに出力します。i

2 番目のものは、返された関数のアウター スコープにを渡し、 name としてエイリアス化されていますval
数値は参照でvalはなく値で渡されるため、内部から変更されない限り、常に同じ値になります。

ループの外で関数を 1 回作成した場合も、これと同じ結果を得ることができます。

var add_log = function (el, val) { el.onclick = function () { console.log(val); }; },
    i = 0,
    el;

for (; i < ........) {
    el = ....
    add_log(el, i);
}

iは値で渡されるため、すべての要素がvalスコープ テーブルに異なる値を持ち、すべての要素が異なる番号をログに記録します。

于 2013-04-07T16:14:16.173 に答える