Я знаю, каково закрытие, но я все еще не понимаю, почему (или когда) Вы использовали бы их

Мое понимание закрытий - то, что они - по существу функция, которая использует переменную, которую Вы приняли бы, будет вне объема. Я предполагаю, вот пример, который я видел на днях:

function closureMaker(somearg)
{
    var local_value = 7;
    function funcToReturn(arg1, arg2)
    {
        return local_value + somearg + arg1 + arg2;
    }
    return funcToReturn;
}
var myClosure = closureMaker(6);  //make the closure
myClosure(2, 3);                  //using it

Теперь закрытие имеет local_value и даже исходный аргумент, somearg. Но я не добираюсь, почему они полезны. Какой смысл того, чтобы использовать 'свободную' переменную local_value или еще более неизвестный мне, почему Вы использовали бы аргумент функции closureMaking в Вашей функции закрытия?

Я интересуюсь больше тем, как это используется в JavaScript, это используется много для запросов Ajax и объектов?

Я добрался какой. Мне нужно почему.

12
задан Rob 9 August 2010 в 16:49
поделиться

7 ответов

Одним из наиболее практичных и широко распространенных способов использования замыканий является реализация частных или привилегированных членов , например, например:

function Test (param) {
  var secret = 3;
  function privateMethod() {
    //...
  }
  this.publicMember = param;
  this.privilegedMember = function () {
    return secret * param;
  };
}

var foo = new Test(10);
foo.privilegedMember(); // 30
foo.secret; // undefined

Модуль шаблон также является хорошим примером, который может использовать тот же принцип, например:

var myModule = (function () { 
  var obj = {}, privateVariable = 1; 

  function privateMethod() { 
    // ... 
  } 

  obj.publicProperty = 1; 
  obj.publicMethod = function () { 
    // private members available here... 
  }; 

  return obj; 
}());
6
ответ дан 2 December 2019 в 21:01
поделиться

Обычно в цикле for вы хотите указать номер счетчика.

function addLinks () {
    for(var i = 0; i < 5; ++i) {
        var link = document.createElement('a');
        link.appendChild(document.createTextNode('Link ' + i));
        link.i = i;
        link.onclick = function() { alert( i ) };
        document.body.appendChild(link);
    }
}

addLinks();

Когда вы переходите по этим ссылкам, появляется предупреждение 5 , потому что цикл уже выполнен, а i равно 5 . Мы не «сохраняли» состояние i во время выполнения цикла for.

Мы можем сделать закрытие, чтобы «сохранить» это состояние:

function addLinks () {
    for(var i = 0; i < 5; ++i) {
        var link = document.createElement('a');
        link.appendChild(document.createTextNode('Link ' + i));
        link.i = i;
        link.onclick = (function(i) { return function() {  alert(i ) } })(i);
        document.body.appendChild(link);
    }
}

addLinks();

i привязан к самоисполняющимся анонимным функциям, вызываемым в каждом приращении в нашем цикле. Таким образом, состояние сохраняется, и мы получаем правильный # при тревоге.

4
ответ дан 2 December 2019 в 21:01
поделиться

Замыкания - это простой способ создания функций, зависящих от параметров. Или, говоря иначе, создать конкретный экземпляр семейства функций (читайте дальше, если это непонятно) в зависимости от некоторого значения времени выполнения.

Javascript позволяет передавать функции как члены первого класса; так, например, вы можете передать функцию, определяющую, как объединить два целых числа, обратившись к ней напрямую.

Однако, идя на шаг дальше, замыкание позволяет создать "персонализированную" версию функции, точное поведение которой зависит от некоторой переменной времени выполнения (но в остальном она соответствует фреймворку).

Например, вот функция, которая позволяет curried добавление:

function getAddNFunction(n)
{
    function inner(operand)
    {
        return n + operand;
    }
    return inner;
}

Теперь, если вы вызовете getAddNFunction(7), вы получите функцию, которая добавляет 7 к аргументу. Если вы вызовете getAddNFunction(42.5), вы получите функцию, которая добавляет 42.5 к аргументу.

Надеюсь, этот простой пример проясняет преимущество замыканий; они позволяют встраивать аргументы в функцию во время создания, а не передавать их во время выполнения (в конце концов, вызов getAddNFunction(9)(2) точно такой же, как вызов 9 + 2, за исключением того, что два аргумента могут быть предоставлены в разное время).

Например, вы можете захотеть вернуть какую-то сложную функцию разбора XML относительно какого-то корневого элемента; закрытие позволяет вам встроить определение этого корневого элемента в саму функцию, а не зависеть от того, что вызывающая сторона будет иметь к нему доступ всякий раз, когда захочет выполнить функцию.

0
ответ дан 2 December 2019 в 21:01
поделиться

Пример, который вы рассматриваете, пытается показать вам, как работают замыкания. Я думаю о закрытии как о небольших фрагментах кода, которые вы можете передавать. Замечательно то, что (свободные) переменные в замыкании привязаны к текущей лексической области видимости. Вот почему local_value сохраняет значение 7 , потому что это то, чем было значение local_value при создании закрытия.

Javascript реализует замыкания с помощью анонимных функций * , но имейте в виду, что технически это две разные концепции.

В контексте Javascript замыкания (реализованные как анонимные функции) очень полезны, когда вы хотите иметь дело с вещами, которые происходят асинхронно; Хорошим примером являются, как вы заявили, запросы AJAX, в которых вы не можете предсказать, когда вы получите ответ от сервера. В этом случае у вас есть анонимная функция, называемая обратным вызовом , которую вы изначально определяете и передаете при выполнении вызова AJAX. Когда вызов успешно завершается, вызывается ваш обратный вызов для обработки результата. Замыкания приводят к более чистому коду, поскольку вы можете упаковать в них поведение и логику. Это также помогает вам абстрагироваться от поведения наших и разделять проблемы.

Еще одно применение анонимных функций / закрытий - обработка событий. Когда происходит событие, вызывается ваш обработчик событий.

Как я уже упоминал ранее, вы можете абстрагировать поведение и логику и поместить их в закрытие. Но что на самом деле делает закрытие таким мощным, так это контекст . Вы можете настроить поведение закрытия в зависимости от среды, в которой оно было создано. Это делает вашу функцию очень универсальной, потому что вы определяете ее аргументы (которые будут влиять на ее поведение) во время ее создания, а не тогда, когда вы вызываете ее (с явными параметрами) во время выполнения.

Вот хорошая статья о закрытии в Javascript.Он длинный, но информативный:

* Как упоминалось в CMS, именованные функции будут вести себя как анонимные функции, потому что они будут иметь доступ к переменным, которые являются определены в той же лексической области видимости (или что-то еще в цепочке). Это наиболее очевидно в внутренних функциях. Но если задуматься, то же самое происходит с любой функцией; у вас есть доступ к переменным, которые были определены в глобальной области (т. е. глобальным переменным).

4
ответ дан 2 December 2019 в 21:01
поделиться

Возможно, это не совсем то, что вы ищете, но есть отличная статья о замыканиях для Java (как они должны/могут быть реализованы), в которой также рассматриваются некоторые примеры того, где вы захотите их использовать

http://www.youtube. com/watch?v=0zVizaCOhME

0
ответ дан 2 December 2019 в 21:01
поделиться

В дополнение к вышесказанному закрытие помогает скрыть некоторые детали реализации.

var Counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }   
})();

alert(Counter.value()); /* Alerts 0 */
Counter.increment();
Counter.increment();
alert(Counter.value()); /* Alerts 2 */
Counter.decrement();
alert(Counter.value()); /* Alerts 1 */

Еще одна хорошая статья

Прочитайте эту статью о модульном паттерне в javascript, который в значительной степени использует замыкания.

0
ответ дан 2 December 2019 в 21:01
поделиться

Если вы работаете из объектно-ориентированного мира, замыкания позволяют вам создавать, по сути, частные переменные-члены и методы для ваших объектов:

function Constructor(...) {
  var privateVar = value;
  function privateFunc() {
  }
  this.publicFunc = function() {
  // public func has access to privateVar and privateFunc, but code outside Constructor does not
  }
}

Дуглас Крокфорд и доброта javascript

0
ответ дан 2 December 2019 в 21:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: