
В этом уроке мы с вами разберем, что такое замыкания. Замыкания, это именно тот вопрос, который чаще всего задают на собеседованиях. Обычно потому, что люди его не полностью понимают или не могут обьяснить.
Давайте начнем.
Итак представьте, что у нас есть функция, которая добавляет 2 к числу, которое мы указали в функции.
var addTo = function (passed) {
var inner = 2
return passed + inner
}
console.log(addTo(3))
То есть при вызове функции с аргументом 3 мы добавляем 3 + 2 и получаем 5.
Если мы посмотрим в браузер, то оно так и работает.
Теперь изменим код. Давайте уберем аргумент passed. Теперь вопрос: "Откуда мы можем его получить, чтобы он появился внутри функции addTo"?
Мы можем написать passed, как переменную вверху нашей функции и тогда она будет доступна внутри нашей функции.
var passed = 3
var addTo = function () {
var inner = 2
return passed + inner
}
console.log(addTo())
Если мы посмотрим в браузер, то мы получаем такой же результат, как до этого.
В javascript все переменные, который описаны снаружи функций доступны внутри этих функций. Именно поэтому мы можем брать переменную passed снаружи и использовать ее внутри нашей функции.
Теперь давайте усложним наш пример. Давайте внутри нашей функции addTo, которая принимает 1 аргумент passed, создадим еще одну функцию так, как мы их обычно создаем.
var addTo = function (passed) {
var add = function () {
}
}
И вернем созданную функцию не вызывая ее.
var addTo = function (passed) {
var add = function () {
}
return add
}
Теперь давайте добавим в эту функцию один параметр inner и так как мы помним из предыдущего пример, что внутри функции нам доступны внешние переменные, то нам доступна переменная passed в этой функции.
var addTo = function (passed) {
var add = function (inner) {
return passed + inner
}
return add
}
Итак еще раз. Мы описали функцию внутри функции, которая принимает аргумент inner и возвращает passed + inner. passed мы берем извне.
Теперь давайте напишем
var addThree = addTo(3)
console.log(addThree)
В браузере мы увидим, что у нас вывелась функция. И это логично, так как мы описали внутри функцию и ее вернули.
Как вы помните, функции являются обьектами, поэтому давайте посмотрим на свойства этого обьекта.
var addThree = addTo(3)
console.dir(addThree)
Теперь в консоли мы увидим не тело функции, а обьект. И у него есть одно свойство, которое нас интересует. Это свойство [[Scopes]]. Если мы его откроем, то увидим Closure внутри. И внутри Closure у нас и будет наша переменная passed, которую мы передавали как аргумент.
Собственно, Closure в переводе на русский и означает замыкание.
Итак еще раз. Как вы помните все переменные внутри функции создаются при ее вызове и удаляются, после завершения функции.
Но в данном случае мы видим, что функция addTo уже вызвалась, а переменная passed все еще хранится внутри и мы можем ее использовать.
Давайте попробуем вызвать эту функцию еще раз
var addThree = addTo(3)
var addOne = addTo(1)
console.dir(addThree)
console.dir(addOne)
Если мы посмотрим сейчас, то функция вызвалась в обоих случаях и в обоих случаях сохранила внутри себя passed после вызова.
Теперь мы можем этот passed использовать. Собственно он у нас и используется внутри нашей функции add. Но мы эту функцию еще не вызвали. Мы ее только вернули и записали в переменные.
Когда мы ее вызовем сейчас, то у нас будет доступ к переменной passed, так как она сохранилась в замыкании.
var addThree = addTo(3)
var addOne = addTo(1)
console.log(addThree(3))
console.log(addOne(2))
Если мы посмотрим в браузер, то у нас вывелось 6 и 3 соответственно.
Итак давайте подытожим, что такое замыкания.
Это очень часто используемый прием в javascript, который мы будем применять в следующих уроках.
Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео.