0

次のように表示される「名前」の値を取得する際に問題があります。

   for (var name in array) {
        var hoverIn = function() {
                  alert(name);
        };

        var hoverOut = function() {
        };

        thing.hover(hoverIn, hoverOut);

   }

私が得るのは、名前の最後の値を持つ警告ウィンドウです。明らかに私は何か間違ったことをしており、それは簡単な修正だと思います。誰でも助けることができますか?

ありがとう。

4

4 に答える 4

7

それはクロージャの問題ですname。その後、反復が の最後namearrayなり、反復が発生したときにホバーのコールバックがすぐに実行されないため、ホバー関数が実際に実行されると、name常に の最後になりarrayます。

IEFE (即時実行関数式) を使用する必要があります。

   for (var name in array) {
        // pass in name to the anonymous function, and immediately
        // executes it to retain name when the particular iteration happens
        var hoverIn = (function(name) {
             return function() {
                  alert(name);
             }
        })(name); // if you notice, the pattern is (function(name) {})(name) 
                  // the first () creates an anonymous function, the (name) 
                  // executes it, effectively passing name to the anon fn

        var hoverOut = (function(name) {
            // same pattern if you need to re-use name inside here, otherwise just
            // function() { } should suffice
        })(name);

        thing.hover(hoverIn, hoverOut);

   }

(function() { })()@pimvdbが指摘したように、(正直に見るのが面倒です)の重複を避けるために、本体全体をクロージャーでラップすることもできます:

   for (var name in array) {
        (function(name) {
           var hoverIn = function() {
               alert(name);
           }

           var hoverOut = function() {
           }

           thing.hover(hoverIn, hoverOut);
        })(name); // closure of for loop body

   }
于 2012-08-17T09:43:53.870 に答える
0

この問題に対処するには2つの方法があります。

最初に知っておくべきことは、スコープは関数レベルでのみ発生し、javascriptのループ内では発生しないということです。外部ソースから関数内に変数を設定し、それをすぐに実行しない場合、変数はループの過程で変更されます。

他の変数を閉じることでこれを解決できます。

var names = ["john","paul","george","ringo"];
var store = {};

//this function receives the data as a parameter
//so it will be a safe copy.

function createFunc(name){
     //just return a function that will alert the name.
    return function(){
       alert(name);
    }
}
for (var i in names) {

        var hoverIn = createFunc(names[i]);

        store[names[i]]=hoverIn;

}
store["john"]();

もう1つの方法は、ループ内ですぐに実行される無名関数を作成することです。

var names = ["john","paul","george","ringo"];
var store = {};

for (var i in names) {
   //the function receives the i as a parameter
   //and executes, so n is a safe copy of i
  (function(n){

    var hoverIn = function(){
        alert(names[n]);
    }

    store[names[n]]=hoverIn;

  })(i);

}
store["john"]();

すべてが閉鎖に関連する問題です。詳細については、ウィキペディアを参照してください。

于 2012-08-17T10:03:29.473 に答える
0

ループ内に変数を追加する

var thisName = name;

そしてそれを関数で使用します

alert(thisName);
于 2012-08-17T09:43:34.563 に答える
-2

クロージャを作成する必要があります:

 for (var name in array) {
        var hoverIn = (function() {
              return function() {
                  alert(name);
              };
        }());

        var hoverOut = function() {
        };

        thing.hover(hoverIn, hoverOut);
   }
于 2012-08-17T09:43:22.953 に答える