Как правильно исправить это закрытие Javascript? - PullRequest
4 голосов
/ 22 ноября 2011

Я ознакомился с закрытиями JavaScript и наткнулся на эту статью. http://blog.morrisjohns.com/javascript_closures_for_dummies.html

Из-за закрытия Пример 5 работает не так, как ожидалось. Как бы изменить

result.push( function() {alert(item + ' ' + list[i])} );

чтобы код работал?

function buildList(list) { 
  var result = [];
  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push( function() {alert(item + ' ' + list[i])} );
  }
  return result;
}

function testList() {
  var fnlist = buildList([1,2,3]);
  // using j only to help prevent confusion - could use i
  for (var j = 0; j < fnlist.length; j++) {
    fnlist[j]();
  }
}

testList();

Спасибо!

Ответы [ 3 ]

6 голосов
/ 22 ноября 2011
function buildList(list) { 
  var result = [];
  for (var i = 0; i < list.length; i++) {
    (function(i) {
      var item = 'item' + list[i];
      result.push(function() {
        alert(item + ' ' + list[i]);
      });
    })(i);
  }
  return result;
}
3 голосов
/ 22 ноября 2011

Вам нужно, чтобы i и item из разных функций были отдельными переменными в разных областях (чтобы они могли иметь разные значения вместо того, чтобы делиться ими). Поскольку Javascript имеет только область действия функции, вам нужно создать функцию-оболочку, которая будет содержать эти переменные

function buildList(list) { 
  var result = [];

  function make_f(item, i){
    //item and i are now private variables of make_f
    //and wont be shared by the returned closure
    // the other variable in scope (list) is not shadowed so
    // it is still shared but that is not a problem since we
    // never change its value.
    return function() { alert(item + ' ' + list[i]) };
  }

  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push( make_f(item, i) );
  }
  return result;
}

Вы также можете сделать то же самое с анонимной функцией, которая вызывается немедленно (шаблон (function(){}())).

function buildList(list) { 
  var result = [];

  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push( (function (item, i){
        return function(){function() {alert(item + ' ' + list[i])};
    })(item, i) );
  }

  return result;
}
1 голос
/ 22 ноября 2011

Поместите это в ... другое закрытие!

function buildList(list) { 
  var result = [];
  for (var i = 0; i < list.length; i++) {
    result.push((function(item, listItem){
      return function() {
        alert(item + ' ' + listItem);
      };
    })('item' + list[i], list[i]));
  }
  return result;
}

function testList() {
  var fnlist = buildList([1,2,3]);
  // using j only to help prevent confusion - could use i
  for (var j = 0; j < fnlist.length; j++) {
    fnlist[j]();
  }
}

testList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...