Подтвердить что ты не робот

OO Javascript: окончательное объяснение области переменных

Может ли кто-нибудь объяснить объяснение области видимости переменной в JS, поскольку оно применяется к объектам, функциям и закрытию?

4b9b3361

Ответ 1

Глобальные переменные

Каждая переменная в Javascript является именованным атрибутом объекта. Например: -

var x = 1;

x добавляется к глобальному объекту. Глобальный объект предоставляется контекстом script и может уже иметь набор атрибутов. Например, в браузере глобальный объект - это окно. Эквивалентом указанной выше строки в браузере будет: -

window.x = 1;

Локальные переменные

Теперь, если мы изменим это на: -

function fn()
{
    var x = 1;
}

При вызове fn создается новый объект, называемый контекстом выполнения, также называемым областью (я использую эти термины взаимозаменяемо). x добавляется как атрибут этого объекта области видимости. Следовательно, каждый вызов fn получит свой собственный экземпляр объекта области видимости и, следовательно, его собственный экземпляр атрибута x, прикрепленного к этому объекту области видимости.

Закрытие

Теперь давайте рассмотрим следующее: -

function fnSequence()
{
    var x = 1;
    return function() { return x++; }
}

var fn1 = fnSequence();
var fn2 = fnSequence();

WScript.Echo(fn1())
WScript.Echo(fn2())
WScript.Echo(fn1())
WScript.Echo(fn2())
WScript.Echo(fn1())
WScript.Echo(fn1())
WScript.Echo(fn2())
WScript.Echo(fn2())

Примечание. Замените WScript.Echo тем, что записывается в stdout в вашем контексте.

Последовательность, которую вы должны получить: -

1 1 2 2 3 4 3 4

Итак, что здесь произошло? У нас есть fnSequence, который инициализирует переменную x до 1 и возвращает анонимную функцию, которая вернет значение x, а затем увеличит его.

Когда эта функция сначала выполняется, создается объект области видимости, и к этому объекту области видимости добавляется атрибут x со значением 1. Также создается в одном и том же объекте выполнения анонимная функция. Каждый объект функции будет иметь атрибут scope, который указывает на контекст выполнения, в котором он создан. Это создает то, что известно как цепочка областей, к которой мы придем позже. Ссылка на эту функцию возвращается fnSequence и сохраняется в fn1.

Обратите внимание, что fn1 теперь указывает на анонимную функцию и что анонимная функция имеет атрибут scope, указывающий на объект области, в котором все еще есть атрибут x. Это называется closure, где содержимое контекста выполнения по-прежнему доступно после того, как функция, для которой она была создана, завершила выполнение.

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

Цепочка областей

Что произойдет, если функция, выполняемая fn1, выполняется в первый раз? Для выполнения анонимной функции создается новый контекст выполнения. Возвращаемое значение можно найти из идентификатора x. Объект области функции проверяется для атрибута x, но ни один не найден. Здесь происходит цепочка областей действия. Не удалось найти x в текущем контексте выполнения. JavaScript принимает объект, удерживаемый атрибутом области функции, и ищет там x. Он находит это, поскольку область функций была создана внутри выполнения fnSequence, извлекает ее значение и увеличивает его. Следовательно, 1 выводится, а x в этой области увеличивается до 2.

Теперь, когда выполняется fn2, он в конечном итоге привязан к другому контексту выполнения, атрибут x все еще равен 1. Следовательно, выполнение fn2 также приводит к 1.

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

Ответ 2

Переменные, не объявленные с помощью var, являются глобальными по объему. Функции вводят область действия, но обратите внимание, что если блоки и другие блоки не вводят область действия.

Я также мог увидеть много информации об этом с помощью области JavaScript в Google. Это действительно то, что я бы рекомендовал. http://www.digital-web.com/articles/scope_in_javascript/

Ответ 3

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

Переменные привязаны к области, используя ключевое слово var. Все переменные неявно связаны с областью верхнего уровня. Поэтому, если вы опускаете ключевое слово var, вы неявно ссылаетесь на переменную, связанную с верхним уровнем. В браузере верхний уровень - это окно. Обратите внимание, что окно - это переменная, поэтому окно == window.window