var foo = "hello"; var c = (function a () {function b () {var bar = "world"; alert (foo + bar); return bar;} return b;}) () (); alert (foo + c);Этот пример появляется Hello World дважды;
1. Что такое закрытие?
«Официальное» объяснение: так называемое «закрытие» относится к выражению (обычно функции), которое имеет много переменных и среды, связанную с этими переменными, поэтому эти переменные также являются частью выражения.
Я считаю, что немногие люди могут непосредственно понять это предложение, потому что он описал его слишком академически. Я хочу использовать, как создать закрытие в JavaScript, чтобы рассказать вам, что такое закрытие, потому что очень трудно понять определение закрытия, пропустив процесс создания закрытия. Посмотрите на следующий код:
Функция a () {var i = 0; function b () {alert (++ i);} return b;} var c = a (); c ();Этот код имеет две характеристики:
1. Функция B вложена внутри функции A;
2. Функция A возвращает функцию b.
Таким образом, после выполнения var c = a () переменная C фактически указывает на функцию b. После выполнения C () появится окно, чтобы отобразить значение I (первый раз 1). Этот код на самом деле создает закрытие. Почему? Потому что переменная C внешняя функция A относится к функции B внутри функции A, то есть:
Когда внутренняя функция B функции A ссылается на переменную внешнюю функцию A, создается закрытие.
Думаю, вы все еще не понимаете закрытия, потому что вы не знаете, какие закрытия имеют. Давайте продолжим исследовать ниже.
2. Какова функция закрытия?
Короче говоря, функция закрытия состоит в том, что после выполнения и возврата A закрытие делает механизм сбора мусора JavaScript GC не восстанавливать ресурсы, занятые A, потому что выполнение внутренней функции B необходимо полагаться на переменные в A. Это очень простое описание роли закрытия, которое не является профессиональным или строгим, но это примерно означает, что это так. Понимание закрытия требует постепенного процесса.
В приведенном выше примере, после возвращения функции A, я всегда существует, поэтому каждый раз, когда C () выполняется, я является значением I предупреждения после добавления 1.
Тогда давайте представим другую ситуацию. Если A возвращает не функцию B, ситуация совершенно другая. Поскольку после выполнения A B не возвращается во внешний мир A, но на это ссылается только A, и в настоящее время A будет ссылаться только B, поэтому функции A и B ссылаются друг на друга, но не нарушаются внешним миром (упоминаемые внешним миром), функции A и B будут переработаны GC. (Механизм сбора мусора JavaScript будет подробно представлен позже)
3. Микроскопический мир в закрытии
Если мы хотим иметь более глубокое понимание взаимосвязи между закрытием и функцией A и вложенной функцией B, нам необходимо ввести несколько других концепций: среда выполнения функции (контекст вынуждения), активный объект (объект вызова), область применения (сфера действия) и цепочка сферы. Возьмите процесс функции A от определения до выполнения в качестве примера, чтобы проиллюстрировать эти концепции.
1. При определении функции a интерпретатор JS установит цепочку функции Acpome A в «среду», где A расположена при определении A. Если A является глобальной функцией, в цепочке областей есть только оконные объекты.
2. Когда функция A выполняется, a введет соответствующую среду выполнения (контекст обращения).
3. В процессе создания среды выполнения, a сначала добавит атрибут области, то есть область применения A, а ее значение - цепочка областей на шаге 1. То есть цепь объема A.scope = a.
4. Затем среда выполнения создаст активный объект (объект вызова). Активный объект также является объектом с атрибутами, но он не имеет прототипа и не может быть доступен непосредственно через код JavaScript. После создания активного объекта добавьте активный объект в верхнюю часть цепочки прицелов A. В это время цепочка применения содержит два объекта: активный объект a и windo object.
5. Следующим шагом является добавление атрибута аргументов к активному объекту, который сохраняет параметры, передаваемые при вызове функции a.
6. Наконец, добавьте все формальные параметры функции A и ссылки на внутреннюю функцию B в активное объект A. На этом этапе определение функции B завершено, так же как на шаге 3 цепочка функции B, определяется средой, определяемой B, то есть сферой A.
На этом этапе вся функция A завершена от определения до выполнения. В настоящее время A возвращает ссылку на функцию B к C, а цепочка функции B Области содержит ссылку на активное объект функции A, то есть B может получить доступ ко всем переменным и функциям, определенным в A. Функция B ссылается на C, а функция B опирается на функцию A, поэтому функция A не будет переработана GC после его возврата.
Когда функция B будет выполнена, она также будет такой же, как и выше. Следовательно, цепочка применения B во время выполнения содержит 3 объекта: активный объект B, активный объект A и объекта Window, как показано на рисунке ниже:
Как показано на рисунке, при доступе к переменной в функции B порядок поиска должен сначала поиск своего собственного активного объекта, и, если она существует, он вернется. Если его не существует, он будет продолжать искать активный объект функции A и поиск по очереди, пока не найдет. Если он не может быть найден во всей цепочке областей, не определяется. Если есть прототип прототипа объекта для функции B, то после поиска своего собственного активного объекта сначала найдите свой собственный объект прототипа, а затем продолжайте искать. Это механизм поиска переменной в JavaScript.
4. Сценарии применения закрытия
1. Защитите безопасность переменных в функции. Принимая первый пример в качестве примера, в функции A, ко мне можно получить доступ только по функции B, но не может быть доступен через другие каналы, тем самым защищая безопасность I.
2. Поддерживать переменную в памяти. Тем не менее, как и прежде, из -за закрытия, я в функции всегда существует в памяти, поэтому каждый раз, когда C () выполняется, я буду добавлять 1.
Вышеуказанные два момента являются самыми основными сценариями применения для закрытия, и многие классические случаи происходят из этого.
5. Механизм сбора мусора JavaScript
В JavaScript, если объект больше не ссылается, то объект будет переработан GC. Если на два объекта ссылаются друг на друга и больше не ссылаются третьим лицом, то два объекта, на которые ссылаются друг на друга, будут переработаны. Поскольку на функцию A ссылается B, B ссылается на C за пределами A, поэтому функция A не будет переработана после выполнения.
Вышеупомянутая статья полностью понимает, что механизм закрытия - это весь контент, которым я делюсь с вами. Я надеюсь, что вы можете дать вам ссылку, и я надеюсь, что вы сможете поддержать Wulin.com больше.