Объем закрытия в JavaScript - PullRequest
2 голосов
/ 23 марта 2011
function f1(){
    var x = 5;    
    this.f2 = function(){
        var y = 10; 
        function helper(){
            //Do we have x here because of closure as we have y
        }
        setInterval(helper,100);
    }
}

Я новичок в JavaScript. Я делаю new f1(), чтобы создать объект. Как я понял, helper будет иметь доступ к y путем закрытия, но я заметил, что x также доступен внутри helper. Может ли кто-нибудь объяснить мне, почему это так и до какого уровня работает закрытие в JavaScript.

Ответы [ 3 ]

0 голосов
/ 23 марта 2011

Каждая переменная, которую вы определяете, будет видна во всей области действия функции.Если вы хотите, чтобы x не отображался в вспомогательной функции, я рекомендую использовать другой подход:

var f1 = function () {
  var x = 5; //private variable within f1 scope
}

f1.prototype.f2 = function(){
  var y = 10; // private variable within f2 scope
  function helper(){
    // x is no longer available here
    setInterval(helper,100);
  }
}
0 голосов
/ 12 января 2012

Закрытия создаются в соответствии с правилами области видимости в JavaScript функций.Я бы сказал, что основной клиент замыканий состоит в том, что они поддерживают событие состояния после выполнения до тех пор, пока в следующий раз выполнение не вернется к некоторому пути кода, вложенному в него самого.может пройти много уровней.Или, другими словами, вы не ограничиваете область действия функции, вкладывая в нее другую функцию.

x - это переменная, определенная в области действия f1.Затем вы определяете this.f2 для анонимной функции, область которой все еще находится внутри f1.Это означает, что анонимная функция имеет доступ к x так же, как к y.Так же, как у помощника есть доступ к y.Это то, что я подразумеваю под вложенностью вниз.

@ masylum прекрасно описывает, как их разделить: не определяйте x в той же функции, что и f2.

Одно предостережение для всехиз этого: «это» может измениться, и оно не будет следовать той же схеме, изложенной.«this», или объект контекста, отделен от текущей функции, в которой вы находитесь. Так что «this» для f1 будет отличаться от «this» внутри хелпера.Теперь это будет то же самое для анонимной функции, которую вы назначили для f2, потому что вы присвоили ее контексту «this» в f1 (ala this.f2 =).

При этом вы можете решить эту проблемус помощью замыканий.Вы присваиваете «this» новой переменной, а затем можете использовать эту переменную вместо «this».Например:

  function f3() {
    this.isDone = false;
    var that = this;
    function helper() {
      that.isDone = true;
    }
    setTimeout(helper, 100);
  }
  var obj = new f3();
  obj.isDone;  // Will return false.
  ... // Wait 100 ms and ask it again.
  obj.isDone;  // Should be true now.

Надеюсь, я не слишком далеко зашел по касательной с "этим";тем не менее, я знаю, что это может быть источником большой боли, поэтому я хотел поднять ее, если вы столкнетесь с ней.

Позвольте мне представить следующую ошибку.Подумайте о следующем.

 for (var i = 0; i < 3; i++) {
    setTimeout(function() {
      alert(i);
    }, 100);
  }

Если вы запустите этот код, вы увидите предупреждение, которое говорит «3» 3 раза.Это фактически не будет делать счет от 1 до 3. Это распространенная ошибка с замыканиями.Причина в том, что вы выполняете цикл for до конца, прежде чем вызывать обратный вызов в setTimeout.Поэтому, когда пришло время анонимной функции разрешить то, что я есть, она каждый раз обнаруживает, что она равна 3.

Вы можете прочитать об этом подробнее в http://www.mennovanslooten.nl/blog/post/62 и https://developer.mozilla.org/en/JavaScript/Guide/Closures#Creating_closures_in_loops:_A_common_mistake

0 голосов
/ 23 марта 2011

Причина, по которой x и y видны внутри функции helper (), заключается в том, что вы сделали их глобальными для любой функции внутри f1 () с помощью ключевого слова var. Если бы вы определили обе переменные без ключевого слова var, они не были бы видны внутри функции helper ().

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