Что такое замыкание?

Замыкания — это функции, ссылающиеся на независимые (свободные) переменные. Другими словами, функция, определённая в замыкании, «запоминает» окружение, в котором она была создана.
источник

Только изучаю js. Поэтому вопрос:

Правильно ли я понимаю, что

замыкание js - это функция внутри другой функции ("обертки"), которая использует переменные этой функции "обертки" ?

Принцип работы, вроде, как понял, но не могу своими словами сказать что это!
  • Вопрос задан
  • 31618 просмотров
Решения вопроса 2
@HowardRoark
Full stack developer
Мне кажется, самый простой пример замыкания - это счетчик.
var counter = (function () {
	var current = 0;
	return function () {
		current++;
		return current;
	}
})();

console.log(counter()); // 1
console.log(counter()); // 2

В данном случае мы не имеем доступ к переменной current и функция гарантированно возвращает каждый раз уникальное значение.
Если бы это была простая функция, то переменная, содержащая состояние (current), должна была бы находиться вне функции.
var current = 0;
var counter = function () {
	current++;
	return current;
}

console.log(counter()); // 1
current = 5;
console.log(counter()); // 6

А это уже нарушает принцип "черного ящика", т.к. переменной можно присвоить другое значение в любом месте.
Ответ написан
DzodzikovAK
@DzodzikovAK
Java Developer
Замыкание - это функция, содержащая в себе ссылки на переменные из внешней области видимости. Т.е. она "замыкает" внешние переменные в себе.

Собственно, это один из двух видов анонимных функций: есть лямбда-функции, есть замыкания (clojures). В этом их отличие.

замыкание js - это функция внутри другой функции ("обертки")

Нет, замыкание не обязательно является вложенной функцией.
Ответ написан
Пригласить эксперта
Ответы на вопрос 9
iCoderXXI
@iCoderXXI
React.JS/FrontEnd engineer
В целом ты все верно понял. Почитал я тут ответы, термины, термины, термины...

Я люблю простые объяснения, буквально на пальцах.

Вот ты вызвал функцию, в ней создаются переменные локальной области видимости, т.е. доступные только самой функции. Под эти переменные движок JavaScript выделяет память.

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

В случае с замыканием, ты возвращаешь функцию обратно, т.е. ссылки остаются, поэтому движок не может освободить память, и переменные остаются доступными функции, и более никому. Поэтому эта штука и называется замыкание, т.к. переменные замкнуты на саму функцию.

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

Один из основных паттернов, для которых применяются замыкания - ограничение доступа к данным, их изоляция (ограничение их области видимости).

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

В ответах есть пример со счетчиком, который наглядно демонстрирует этот принцип.
Ответ написан
@tetafro
var a = 42;
function b() { return a; }

Вот замыкание в самом простом виде. Функция привяжется к переменной a и будет её возвращать каждый раз.
Ответ написан
Комментировать
vicodin
@vicodin
Имею некоторый опыт
https://hackernoon.com/how-my-10-year-old-learned-... - вот тут парень писал, как учил 10-летнего сына javascript'у, если ребенок понял, то вы уж точно должны:
Closures

This was fun! CodeSchool did a great job in Javascript Road Trip Part 3, but it just didn’t click for my son right away. Closures still trip me up to this day.

My first explanation attempt:
“A closure is like a dinosaur fossil — a snapshot from a moment in time preserved for millions of years. You can get still get information about the dinosaur from the fossil, even though the dinosaur itself has been gone for millions of years.”

Closures were starting to make sense, so I tried using cookies again . . .
“Let’s say I go to the same bakery every day and ask the baker for a cookie. The first thing he/she asks is, ‘What kind of cookie do you want?’ After a few days, the baker might already know what cookie I like and simply ask, ‘The usual?’. By saving my cookie choice in memory, he/she is able to reuse the same function from the previous day to get me the proper cookie without having to ask again.”

Eh… It was still a bit fuzzy, until my son asked me…
“So, it’s like when we go to the barber and he just cuts our hair without asking what we want? He always asks new customers how they want him to cut, but never asks us anymore.”

Ding, ding, ding! He got it!!!
Ответ написан
abyrkov
@abyrkov
JavaScripter
Замыкание это крайне простая вещь, если ее рассматривать лексические области видимости как объекты.
Например:
// Текущая область видимости - window
var a = 'window';
function something() {
  // Текущая область видимости inner1
  var b = 'inner1';
  return function() {
    // Область inner2
    return b; // Это замыкание
    // b нет в inner2, берется b из inner1
}
var closure = something(); // Функция с замнкнутой переменной называется тоже замыканием
closure() // => inner1, область осталась той же
Ответ написан
bubandos
@bubandos
bash'у, javascript'ую, php'лю, css'аю, html'каю
Раз в три месяца этот вопрос тут появляется.
Определение замыкания дано в вопросе.
Относительно javascrtipt замыкание - это копирование родительской области видимости (а стало быть всех переменных в ней) в дочернюю.
А область видимости в javascript ограничивается функциями.
Наглядный пример:
var a="a"
var f1 = function () {
    var b = "b";
    var f1_1 = function() {
        var c = "c";
        // у дочерней функции f1_1 есть доступ к переменной a из глобальной области видимости
        // к переменной b из области видимости функции f1
        // к переменной c из локальной области видимости функции f1_1
        console.log(a); // выведет a
        console.log(b); // выведет b
        console.log(c); // выведет c
    }
    // у функции f1 есть доступ к переменной a из глобальной области видимости
    // к переменной b из области видимости функции f1
    // переменная c, определенная в локальной области видимости функции f1_1, не видна
    console.log(a); // выведет a
    console.log(b); // выведет b
    console.log(c); // выведет undefined
}
// в глобальной области видимости видна только переменная a
// и функция f1, которая также находится в глобальной области видимости
console.log(a); // выведет a
console.log(b); // выведет undefined
console.log(c); // выведет undefined


Для большинства повседневных задач подобного объяснения будет достаточно.
Ответ написан
Комментировать
@f_ban
Другими словами, это такой механизм "замораживания" объектов, попавших в лексическое окружение замыкания. Сборщик мусора не удалит замороженое лексическое окружение до тех по, пока существует/используется объект-замыкание, имеющий ссылку на лексическое окружение.
Ответ написан
denis24
@denis24
Интересный человек.
Правильно понимаете.
Ответ написан
Комментировать
dmitry_pavlov
@dmitry_pavlov
World-class .NET freelance contractor (remotely)
Комментировать
@RKuzovlev
Замыкания лучше рассматривать вместе с понятием "область видимости". Можете ознакомиться с этим подробнее в видео https://www.youtube.com/watch?v=uI-hjpmNeYI
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
21 нояб. 2024, в 19:31
500 руб./за проект
21 нояб. 2024, в 19:28
200000 руб./за проект