Лямбда-выражение C # также имеет замыкания, но редко обсуждается сообществами или книгами C #. Я вижу гораздо больше людей и книг о JavaScript, которые говорят о его закрытии, чем в мире C #. Это почему?
Лямбда-выражение C # также имеет замыкания, но редко обсуждается сообществами или книгами C #. Я вижу гораздо больше людей и книг о JavaScript, которые говорят о его закрытии, чем в мире C #. Это почему?
Ответы:
Потому что у javascript нет таких функций, как пространства имен, и вы можете легко испортить все виды глобальных объектов.
Поэтому важно иметь возможность изолировать некоторый код в его собственной среде выполнения. Закрытие идеально подходит для этого.
Такое использование замыкания не имеет смысла в языке, подобном C #, где у вас есть пространства имен, классы и т. Д., Чтобы изолировать код и не помещать все в глобальную область видимости.
Очень распространенная практика для кода javascript - это писать так:
(function(){
// Some code
})();
Как видите, это объявление анонимной функции, за которым сразу следует ее выполнение. Таким образом, ко всему определенному внутри функции невозможно получить доступ извне, и вы не испортите глобальную область видимости. Контекст выполнения этой функции будет оставаться активным до тех пор, пока его использует некоторый код, например, вложенные функции, определенные в этом контексте, которые вы можете передать как обратный вызов или как угодно.
Javascript - это совершенно другой язык, чем C #. Он не объектно-ориентированный, он ориентирован на прототип. Это приводит к очень различным практикам в конце.
В любом случае замыкания хороши, так что используйте их даже в C #!
РЕДАКТИРОВАТЬ: После некоторого обсуждения чата stackoverflow, я думаю, что этот ответ должен быть точным.
Функция в примере кода не является замыканием. Однако эта функция может определять локальные переменные и вложенные функции. Все вложенные функции, которые используют эти локальные переменные, являются замыканиями.
Это полезно для совместного использования некоторых данных в наборе функций без нарушения глобальной области видимости. Это наиболее распространенное использование замыкания в JavaScript.
Замыкание гораздо эффективнее, чем просто делиться такими данными, но давайте будем реалистами, большинство программистов ничего не знают о функциональном программировании. В C # вы бы использовали класс или пространство имен для такого рода использования, но JS не предоставляет эту функциональность.
С закрытием вы можете сделать гораздо больше, чем просто защитить глобальную область, но это то, что вы увидите в исходном коде JS.
Возможно, потому что популярные реализации объектной ориентации JavaScript зависят от замыканий. Давайте посмотрим на простой пример:
function counter() {
var value = 0;
this.getValue = function() { return value; }
this.increase = function() { value++; }
}
var myCounter = new counter();
console.log(myCounter.getValue());
myCounter.increase();
console.log(myCounter.getValue());
Методы getValue
и increase
на самом деле являются замыканиями, инкапсулирующими переменную value
.
Потому что многие из библиотек, которые делают JavaScript «терпимым», используют их.
Взгляните на JQuery , Prototype или MooTools , просто чтобы назвать три популярных. Каждая из этих библиотек предоставляет each
метод для своих коллекций в качестве предпочтительного способа итерации, который использует функцию итератора. Эта функция при доступе к значениям во внешней области будет закрыта:
[1,2,3].each(function(item) {
console.log(item);
});
И это не останавливается на достигнутом: обратные вызовы в Ajax, обработка событий в Ext.js и т. Д. Все принимают функции, и если вы не хотите наполнять свой код сотнями функций, которые вызываются ровно один раз, замыкания - это путь.
console.log
определяется во внешней области видимости, console
как и «свободная переменная». И почему, по сути, цикл for, который ничем не отличается, плохая практика?
Я согласен с другими ответами, что «хорошее» кодирование с помощью JavaScript в большей степени зависит от замыканий. Однако, в дополнение к этому, это, вероятно, просто вопрос того, как давно эта функция существует на каждом языке. JavaScript в основном имел замыкания с самых ранних реализаций. C #, с другой стороны, имел их только с версии 3.0, которая была выпущена в Visual Studio 2008.
Многие программисты на C #, с которыми я сталкиваюсь, все еще работают над проектами 2.0. И даже если они работают в 3.0 или 4.0, они часто все еще используют идиомы 2.0. Я люблю замыкания; надеюсь, они будут более активно использоваться в C #, поскольку эта концепция распространяется среди разработчиков C #.
Основная причина в том, что C # статически типизирован, а функции имеют доступ только к единственной, заранее определенной среде, что препятствует полезности замыканий.
В JavaScript, с другой стороны, замыкания позволяют функциям вести себя как методы, когда к ним обращаются как к свойству объекта и как к объектам первого класса, их также можно вводить в разные среды, что позволяет подпрограммам работать в разных контекстах.
Одна из причин, по которой мне пришлось узнать о них, заключается в том, что когда вы просматриваете элементы DOM (или что-то еще), вы хотите иметь возможность «закрывать» или «инкапсулировать» область видимости переменной. Как и в примере, размещенном здесь: /programming/5606059/how-to-create-closure-in-loop-and-store-it-in-variable-for-later-execution