Какая разница между глобальным 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а]