Страницы

Поиск по вопросам

среда, 22 января 2020 г.

Нужна помощь в понимании замыканий [дубликат]

#javascript #замыкания


        
             
                
                    
                        
                            На этот вопрос уже даны ответы здесь:
                            
                        
                    
                
                        
                            Как работают замыкания в JavaScript
                                
                                    (7 ответов)
                                
                        
                                Закрыт 2 года назад.
            
                    
Знаю что написано на эту тему уже немало, но всё же

Итак, шло все как по маслу (в плане изучения js) пока я к замыканиям не дошел) читаю,
смотрю ролики на эту тематику - и просто ну нивкакую не могу понять, как это работает
и зачем это нужно..?
если с определением/пониманием что такое замыкания более менее понятно... хотя тут
тоже все не так однозначно... вот что пишут несколько источников по даному вопросу:


  MDN: Замыкание — это комбинация функции и лексического окружения, в
  котором эта функция была определена.
  
  javascript.ru: Замыкание – это функция вместе со всеми внешними
  переменными, которые ей доступны.


в неткоторых недалеких источниках: 


  это функция внутри другой функции


)

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

перейдём непосредственно к коду

вот пример замыканий с сайта w3schools:





Counting with a local variable.

0

Вопрос - зачем нужны все эти renurn'ы? если первый как я понимаю еще возвращает функцию, то зачем нужен второй и почему без него у counter'a значение undefined? function makeAdder(x) { return function(y) { return x + y; }; }; var add5 = makeAdder(5); var add10 = makeAdder(10); console.log(add5(2)); // 7 console.log(add10(2)); // 12 почему нельзя поставить измененные параметры сразу при вызове (напр., makeAdder(2) а не (add5(2)) ), то есть зачем нужно сперва присваивать функцию в переменную? процитирую наконец еще один источник (тот же MDN): Замыкания — это функции, ссылающиеся на независимые (свободные) переменные. Другими словами, функция, определённая в замыкании, «запоминает» окружение, в котором она была создана. Это окружение состоит из произвольного количества локальных переменных, которые были в области действия функции во время создания замыкания. что здесь понимается под "окружением" кроме переменных или только переменные? насколько "долго" замыкание может помнить такое окружение? p.s. не кидайтесь тапкми за возможно по нубски сформулированные вопросы)


Ответы

Ответ 1



Можете почитать по дубликату о подробностях. При создании функции, ей создаётся ссылка на родительское окружение, в котором она создана. Т. е. при отсутствии у себя в окружении, допустим, переменной, движок может пойти по ссылке в родительский скоуп и там отыскать. Функция add вызывается сама при создании, возвращает новую функцию, но с захваченной переменной-счетчиком в замыкании. При вызове add, сработает внутренняя функция, изменит значение и вернёт его. Почему return нужен? Ну без него функции возвращают undefined (кроме стрелок. Иногда). Синтетический пример просто. Но показывающий возможности замыкания - создал фабрикой (паттерн) особую функцию, уже заряженную чем-либо (тут просто особенной цифрой) и можно ею манипулировать, зная что везде, где применяешь, будут заданные ранее параметры. Представим функцию, при создании которой всегда создаётся её окружение (кладём туда переменные, определённые в ней, внутреннюю информации и т. п.). Внутри создаём ещё одну функцию, для которой тоже создаётся объект окружения, но так же есть сокрытое от программиста свойство [[scope]], которое ссылается на родительский объект окружения. При обращении внутренней функции к переменной, сначала смотрится собственное окружение. Если нету - идём к родителю. Если и там нет - к его родителю. И так до конца - объекта global (window в браузерах). В картинках: function b(){ | b.LexicalScoping = {x: 42, c: function} | b.[[scope]] = window let x = 42; function c(){ | c.LexicalScoping = {y: 3} | c.[[scope]] = b.LexicalScoping let y = 3; alert(w); } } Когда интерпретатор выполняет alert(w), он ищет переменную w и смотрит так: c.LexicalScoping, если пусто - c.[[scope]]. Если и там пусто - b.[[scope]]. Если и там нет - выбросит ошибку. Это, конечно, не копирка стандартов, но для новичка объяснение нормально, так что не надо тут флагать, @Grundy!

Комментариев нет:

Отправить комментарий