Какая разница между глобальным var и window.variable в javascript?
Я читаю документы backbone.js и вижу много кода, который присваивает атрибуты объекту window:
window.something = "whatever";
какая разница между вызовом этого кода и просто назначением переменной и созданием глобального var, например:
something = "whatever";
Я предполагаю, что существует какая-то разновидность разницы и/или разность владения объектами (окно является владельцем vs not), но меня интересует деталь между ними и почему я буду использовать окно, а не использовать его.
Ответы
Ответ 1
Никакой разницы. Они имеют одинаковый эффект (в браузере, где window
- глобальный контекст 1).
-
window.foo = "bar"
устанавливает свойство foo
на window
.
-
foo = "bar"
указывает либо опечатку, либо намеренно глобальную.
Так как мне приходится дважды проверять, является ли это опечаткой или нет, я лично считаю более удобочитаемым напрямую установить window.foo
.
Кроме того, в строгом режиме ES5 foo = "bar"
является незаконным назначением, потому что foo
не объявляется и будет вызывать Error
.
Изменить:
Как отмечено в комментариях, foo = "bar"
будет искать путь вверх по цепочке видимости переменной foo
и повторно назначить ее с помощью "bar"
, если она будет найдена. Если он не найден, он создаст новую глобальную переменную.
Также с window.foo = "bar"
вы просто назначаете свойство объекту, которое можно удалить с помощью delete window.foo
.
В строгом режиме ES5 это недействительно для переменной delete
.
1 В других средах, таких как node.js и Web Workers, может быть другое имя для глобального объекта, а window
может вообще не существовать. node.js использует global
, а веб-рабочие используют self
.
Ответ 2
Оба они делают то же самое.
Но, получив доступ к свойству window
, вы точно знаете, что получаете доступ к глобальной переменной независимо от того, в какой области вы находитесь.
Например:
globalVar = "smth";
function(){
var globalVar = 2;
alert(globalVar);// points to the current scope globalVar
alert(window.globalVar);// points to the original globalVar
}
Другими словами, если вы хотите работать с глобальными переменными, несколько безопаснее обращаться к ним через свой контейнер: window.variable
Ответ 3
Ключ, на который ссылается Райнос, заключается в том, что он явно установлен на объект окна. В браузере глобальный объект совпадает с объектом окна, но в других средах (например, node.js или, возможно, выполняется в виде веб-представления какого-либо типа на мобильном устройстве), это может быть не так.
Ответ 4
Разница в том, что window.foo = bar;
не может быть перехвачен рефакторингом, сделанным позже.
Использование foo = bar;
означает, что если в более поздний срок код будет перемещен в закрытие, где var foo
определено, он больше не будет устанавливать его на глобальном объекте.
Ответ 5
Добавление еще одной точки:
Если вы ссылаетесь на необъявленную переменную напрямую (без использования - window или typeof), то вы получите переменную, не определенную ошибку.
Примеры:
// var unDecVariable
if (unDecVariable != null) // Error: unDecVariable is not defined
{
// do something
}
if (window.unDecVariable != null) // No Error
{
// do something
}
if (typeof unDecVariable != 'undefined' && unDecVariable != null) // Alternative way
{
// do something
}
Ответ 6
Неразрешенные ссылки (aka undeclared variables) на самом деле не являются переменными, они добавляются как свойство для глобального объекта. [5c]
В строгом режиме ("use strict") нерешенные ссылки бросают ReferenceError. Это делается для того, чтобы не добавлять свойства к глобальному объекту, предназначенному для объявления переменных. В этом случае, если вы хотите добавить свойство к глобальному объекту, вы должны использовать window.foo = "bar". [5а]