Является ли окно действительно глобальным в Javascript? - PullRequest
26 голосов
/ 13 июля 2011

Возьмите этот кусок Javascript в браузере:

<script>

console.log(window.someThing);
var x = 12;

function foo() {
   window.otherThing = x;
}

</script>

Внутри foo мы можем получить доступ к window, мы все это знаем, но почему именно?

  • Это какая-то особая глобальная переменная?
  • Или «корневая область» (внутри тега script) имеет его как неявную локальную переменную, и она просто «наследуется по замыканию», как и любая другая локальная переменная (как x выше)?

И как это согласуется с переменными, объявленными непосредственно внутри тега script, которые задаются как свойства window? (Или это не так?)

<script>
var x = 12;
function() {
   console.log(window.x);
}
</script>

Ответы [ 7 ]

23 голосов
/ 13 июля 2011

Причиной, по которой вы можете получить доступ к «вне области» или «свободным» переменным в ECMAscript, является так называемая Scope chain .Цепочка контекста является специальным свойством каждого контекста выполнения .Как уже упоминалось несколько раз ранее, объект контекста выглядит как минимум:

  • [[scope]]
  • Переменная / объект активации
  • «this» значение контекста

каждый раз, когда вы обращаетесь к переменной (-name) в контексте (например, к функции), процесс поиска всегда начинается в своем собственном Activation Object.Все формальные параметры, объявления функций и локально определенные переменные (var) хранятся в этом специальном объекте.Если имя переменной не было найдено в этом объекте, поиск идет в [[Scope]] -цепь.Каждый раз, когда функция (-context) инициализируется, она будет копировать все родительские контекстные переменные / объекты активации во внутреннее свойство [[Scope]].Это то, что мы называем лексическим охватом .Вот почему Closures работают в ECMAscript.Поскольку Global context также имеет Variable Object (точнее, ** переменным объектом для глобального объекта является сам глобальный объект), он также копируется в свойство [[Scope]] .

Именно поэтому вы можете получить доступ к window из любой функции: -)

Приведенное выше объяснение имеет один важный концептуальный вывод: любая функция в ECMAscript является Closure , что правда.Поскольку каждая функция по крайней мере скопирует глобальный контекст VO в своем свойстве [[Scope]] .

14 голосов
/ 13 июля 2011

Является ли окно действительно глобальным в Javascript?

Да. Если вы не создадите новую переменную с именем window в более узком объеме

function foo() {
    var window;
}

Внутри foo мы можем получить доступ к окну, мы все это знаем, но почему именно?

Любая функция может обращаться к переменным, объявленным в более широкой области. Там нет ничего особенного в окне.

7 голосов
/ 13 июля 2011

Все это определено в ECMAScript.

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

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

ES 10.2.3 Глобальная среда :

Глобальная среда - это уникальная лексическая среда, которая создается перед выполнением любого кода ECMAScript.Запись среды глобальной среды - это запись объектной среды, чей объект привязки является глобальным объектом (15.1).Ссылка на внешнюю среду глобальной среды равна нулю.

По мере выполнения кода ECMAScript к глобальному объекту могут добавляться дополнительные свойства, а исходные свойства могут быть изменены.

ES 15.1 Глобальный объект

Уникальный глобальный объект создается до того, как элемент управления входит в любой контекст выполнения.

Если не указано иное, стандартные встроенные свойства глобального объектаиметь атрибуты {[[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}.

Глобальный объект не имеет внутреннего свойства [[Construct]];невозможно использовать глобальный объект в качестве конструктора с оператором new.

Глобальный объект не имеет внутреннего свойства [[Call]];невозможно вызвать глобальный объект как функцию.

Значения внутренних свойств [[Prototype]] и [[Class]] глобального объекта зависят от реализации.

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

6 голосов
/ 13 июля 2011

Это связано с цепочкой областей действия .

Посмотрите на следующую презентацию Николаса С. Закаса .(начиная с мин 5)

3 голосов
/ 13 июля 2011
Окно

- это базовая область действия всех объектов javascript, и оно автоматически «присоединяется» к каждой определяемой вами переменной, если только вы не используете «var» перед объявлением, в этом случае область действия переменной является локальной (это означает, что онасодержится внутри родительской функции или также является глобальным, если вы объявляете свою переменную вне функционального блока).Более того, окно определяется как константа , то есть вы не можете переопределить объект окна (вы получите сообщение об ошибке «ошибка типа: переопределение константного окна»).

так:

window.foo = 5;

это то же самое, что:

var foo = 5;

или:

function() {
foo = 5;
}

но:

function() {
var foo = 5;
}

в этом случае "foo" является локальным (window.foo === undefined)

1 голос
/ 02 июня 2016

Глобальная область действия window применяется только к основному потоку.У веб-работников нет глобальной переменной window.Вместо этого у вас есть WorkerGlobalScope внутри WebWorker и SharedWorkerGlobalScope внутри SharedWorker.

Эта глобальная рабочая область хранится в переменной с именем self и, как описывает ее MDN:

эта область содержит информацию, обычно передаваемую объектами Window .

Это может стать проблемой, когда сторонний код, который вы используете в своем веб-работнике, использует объект окна.Это можно легко решить, объявив переменную window, как предложено @FelipeMicaroniLalli в его ответе , например:

var window = self;
0 голосов
/ 13 июля 2011

В книге Javascript: The Good Parts , как я понимаю, Дуглас Крокфорд объясняет, что window - это глобальный объект веб-браузера, который содержит все глобальные переменные.Это как одно кольцо ...

...