Есть ли разница между объявлением переменной:

var a=0; //1

… таким образом:

a=0; //2

… или:

window.a=0; //3

в глобальной области видимости?

Да, есть пара отличий, хотя на практике они обычно невелики.

Есть четвертый путь, а с ES2015 (ES6) есть еще два. В конце я добавил четвертый способ, но вставил пути ES2015 после # 1 (вы поймете, почему), поэтому мы имеем:

var a = 0;     // 1
let a = 0;     // 1.1 (new with ES2015)
const a = 0;   // 1.2 (new with ES2015)
a = 0;         // 2
window.a = 0;  // 3
this.a = 0;    // 4

Эти утверждения объяснены

{**** } 1 var a = 0;

Это создает глобальную переменную, которая также является свойством Глобальный объект , к которому мы обращаемся как window в браузерах (или через this глобальную область видимости в нестрогом коде). В отличие от некоторых других свойств, свойство не может быть удалено черезdelete Глядя на вывод

Mozilla в терминах спецификации создает привязку идентификатора . Если вы хотите, чтобы экземпляры имели свои собственные массивы, создайте их в функции, а не в прототипе. 2. С поддержкой слияния и создания цепочек аргументов типа массива Запись среды для глобальная среда . Это делает его свойством глобального объекта, потому что в глобальном объекте хранятся привязки идентификаторов для объекта глобальной записи среды. Вот почему свойство не удаляется: это не просто свойство, это привязка идентификатора.

Привязка (переменная) определяется перед выполнением первой строки кода (см. «Когда var случается ниже).

». Обратите внимание, что в IE8 и более ранних версиях свойство, созданное в window Что касается PHP (или, вообще говоря, веб-сервера в целом), HTML-страница не сложнее, чем большая строка. enumerable (не отображается в { *}). В IE9, Chrome, Firefox и Opera это перечислимо. for..in # 1.1


Это создает глобальную переменную, которая let a = 0;

В терминах спецификации, создает привязку идентификатора. в не Повторная установка false из события JavaScript обычно отменяет поведение «по умолчанию» — в случае ссылок оно говорит браузеру не переходить по ссылке.

декларативной записи среды для глобальной среды, а не в записи окружения . Глобальная среда уникальна тем, что имеет разделенную запись среды, одну для всех старых вещей, которые идут в глобальный объект ( 2. С поддержкой слияния и создания цепочек аргументов типа массива Запись окружения) и еще один для всего нового ( 2. С поддержкой слияния и создания цепочек аргументов типа массива и функций, созданных let, const), которые не идут в глобальный объект. class Привязка

создана перед выполнением любого пошагового кода в включающем его блоке (в данном случае, перед выполнением любого глобального кода), но это никоим образом не , пока пошаговое выполнение не достигнет оператора . Поэтому лучшим способом добавления динамически создаваемого свойства является метод [скобка]. . После исполнения достигает оператора let, переменная доступна. (См. «Когда let произойдет» ниже.) let и const # 1.2


Создает глобальную константу, которая не является свойством глобального объекта. const a = 0;

точно так же, как

const, за исключением того, что вы должны предоставить инициализатор (часть let), и вы не можете изменить значение константы после ее создания. Под обложками это точно так же, как = value, но с привязкой к идентификатору, указывающей, что его значение нельзя изменить. Использование let делает для вас три вещи: const Вызывает ошибку времени разбора, если вы пытаетесь присвоить константу.

  1. Позволяет оптимизировать движок JavaScript, исходя из того, что он не изменится.
  2. Документирует его неизменную природу для других программистов.
  3. # 2

Это создает свойство для глобального объекта a = 0;

. Поскольку это нормальное свойство, вы можете удалить его. Я бы порекомендовал Почему решение сделать это, это может быть непонятно любому, кто читает ваш код позже. Если вы используете строгий режим ES5, выполнение этого (присвоение несуществующей переменной) является ошибкой. Это одна из нескольких причин использовать строгий режим. не И что интересно, опять же в IE8 и более ранних версиях свойство не создавало

перечислимых операторов). Это странно, особенно учитывая # 3 ниже. (не отображается в { *}). В IE9, Chrome, Firefox и Opera это перечислимо. for..in # 3


Это явно создает свойство для глобального объекта с использованием window.a = 0;

global, который ссылается на глобальный объект (в браузерах ; некоторые не браузерные среды имеют эквивалентная глобальная переменная, такая как window в NodeJS). Поскольку это нормальное свойство, вы можете удалить его. global перечислимо, в IE8 и более ранних версиях, и в любом другом браузере, который я пробовал.

Это свойство закрытие. Функция не должна # 4


Точно так же, как # 3, за исключением того, что мы ссылаемся на глобальный объект через this.a = 0;

вместо глобального this. Это не будет работать в строгом режиме, потому что в глобальном коде строгого режима window не имеет ссылки на глобальный объект (вместо этого у него есть значение this). undefined Удаление свойств


Что я подразумеваю под «удалением» или «удалением» ключевого слова

: a? Именно это: Удаление свойства (полностью) через delete полностью удаляет свойство из объекта. Вы не можете сделать это с помощью свойств, добавленных к

window.a = 0;
display("'a' in window? "   ('a' in window)); // displays "true"
delete window.a;
display("'a' in window? "   ('a' in window)); // displays "false"

delete косвенно через window, либо игнорируется, либо выдает исключение (в зависимости от реализации JavaScript и от того, находитесь ли вы в строгом режиме). var, delete: Снова IE8 (и, по-видимому, ранее, и IE9-IE11 в сломанном режиме «совместимости»): он не позволит вам удалить свойства объекта

Warning {* } Итак, подведем итог: когда вы делаете , даже если вам это разрешено. Хуже того, он выдает window исключение при попытке ( попробуйте этот экспериментальный объект , вы должны быть осторожны: в IE8 и в других браузерах). Поэтому при удалении из window при попытке удалить свойство, и если выдается исключение, делает следующую лучшую вещь и устанавливает свойство

try {
    delete window.prop;
}
catch (e) {
    window.prop = undefined;
}

применяется кundefined Глядя на вывод

this only Mozilla применяется к объекту window и только (насколько я знаю) к IE8 и более ранним версиям (или IE9-IE11 в нарушенном режиме «совместимости»). Другие браузеры могут удалять свойства window в соответствии с приведенными выше правилами.


Когда происходит var Mozilla случается

Переменные, определенные с помощью оператора var, создаются до того, как запускается пошаговый код любым в контексте выполнения, и поэтому свойство существует хорошо до { *} заявление. обработчик var Это может сбивать с толку, поэтому давайте посмотрим:

Пример из жизни:

display("foo in window? "   ('foo' in window)); // displays "true"
display("window.foo = "   window.foo);          // displays "undefined"
display("bar in window? "   ('bar' in window)); // displays "false"
display("window.bar = "   window.bar);          // displays "undefined"
var foo = "f";
bar = "b";
display("foo in window? "   ('foo' in window)); // displays "true"
display("window.foo = "   window.foo);          // displays "f"
display("bar in window? "   ('bar' in window)); // displays "true"
display("window.bar = "   window.bar);          // displays "b"

Как видите, символ

display("foo in window? "   ('foo' in window)); // displays "true"
display("window.foo = "   window.foo);          // displays "undefined"
display("bar in window? "   ('bar' in window)); // displays "false"
display("window.bar = "   window.bar);          // displays "undefined"
var foo = "f";
bar = "b";
display("foo in window? "   ('foo' in window)); // displays "true"
display("window.foo = "   window.foo);          // displays "f"
display("bar in window? "   ('bar' in window)); // displays "true"
display("window.bar = "   window.bar);          // displays "b"

function display(msg) {
  var p = document.createElement('p');
  p.innerHTML = msg;
  document.body.appendChild(p);
}

определен перед первой строкой, а символ foo — нет. Там, где есть оператор bar, на самом деле есть две вещи: определение символа, которое происходит до запуска первой строки кода ;, и выполнение присваивания этому символу, что происходит там, где строка находится в шаге пошаговый поток. Это известно как «var foo = "f"; подъем», потому что часть var остается в своем первоначальном расположении. (См. var foo перемещается («поднимается») в верхнюю часть области видимости, но объект foo = "f" В моем маленьком анемичном блоге.) Неправильное понимание var Когда


случается, let и const отличаются от

let и const несколькими способами. Способ, который имеет отношение к этому вопросу, заключается в том, что, хотя определяемая ими привязка создается до запуска любого пошагового кода, это не будет var, пока не будет достигнут оператор . Поэтому лучшим способом добавления динамически создаваемого свойства является метод [скобка]. . let или const Итак, пока это выполняется:

Это выдает ошибку:

display(a);    // undefined
var a = 0;
display(a);    // 0

Два других отличия

display(a);    // ReferenceError: a is not defined
let a = 0;
display(a);

от let и const, которые на самом деле не имеют отношения к вопросу: var всегда применимы во весь контекст выполнения (во всем глобальном коде или во всем коде функции в той функции, где она появляется), но

  1. var там, где они появляются. То есть let и const Use — Javascript: The Good Parts имеет функциональную (или глобальную) область видимости, но var имеет область видимости блока. let и const Повторение

  2. в том же контексте безвредно, но если у вас есть var a), наличие другого let a (или const a является синтаксической ошибкой. let a или const a или var a Вот пример, демонстрирующий, что

вступают в силу немедленно в их блоке до запуска любого кода в этом блоке, но недоступны до оператора let и const: let или const Обратите внимание, что второй

var a = 0;
console.log(a);
if (true)
{
  console.log(a); // ReferenceError: a is not defined
  let a = 1;
  console.log(a);
}

завершается ошибкой, вместо этого доступа к console.log извне блока. a Не по теме: избегайте загромождать глобальный объект (


объект становится очень, очень загроможденным свойствами. По возможности, настоятельно рекомендуем не добавлять в беспорядок. Вместо этого оберните символы в небольшой пакет и экспортируйте в { *} один символ для объекта window С чем вы столкнулись

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

(function() {
    var a = 0; // `a` is NOT a property of `window` now

    function foo() {
        alert(a);   // Alerts "0", because `foo` can access `a`
    }
})();

Функцию, используемую таким образом, часто называют scoping function (). Функции, определенные в функции scoping, могут обращаться к переменным, определенным в функции scoping, потому что они

замыкания над этими данными (см .: Замыкания не сложны в моем маленький анемичный блог). Проще говоря: Приведенный выше код дает глобальную переменную области видимости Этот код даст переменную, которая будет использоваться в текущей области видимости, и unde r it

Это обычно то же самое, что и глобальная переменная.

a = 0

Есть ли глобальный объект, от которого все переменные по умолчанию зависают? Например: ‘объявление globals.noVar’

var a = 0;

Не по теме: избегайте беспорядка

window.a = 0;

Это пример его идеи:

<title>Index.html</title>
<script>
    var varDeclaration = true;
    noVarDeclaration = true;
    window.hungOnWindow = true;
    document.hungOnDocument = true;
</script>
<script src="external.js"></script>

/* external.js */

console.info(varDeclaration == true); // could be .log, alert etc
// returns false in IE8

console.info(noVarDeclaration == true); // could be .log, alert etc
// returns false in IE8

console.info(window.hungOnWindow == true); // could be .log, alert etc
// returns true in IE8

console.info(document.hungOnDocument == true); // could be .log, alert etc
// returns ??? in IE8 (untested!)  *I personally find this more clugy than hanging off window obj

init.js

После нахождения этого поста, когда я искал себя, я подумал, что должен добавить, что я не думаю, что это решение с наибольшим количеством голосов. самый лучший Он не обрабатывает значения массива (такие как? A = foo & Amp ; a = bar — в этом случае я ожидаю, что a вернет [‘foo’, ‘bar’]). Кроме того, насколько я могу судить, не учитываются закодированные значения — такие как шестнадцатеричная кодировка символов, где % 20 представляет пробел (пример:? A = Hello % 20World) или используемый символ плюс представлять пробел (пример:? a = Hello World). может быть использован: Сегодня многие страницы в Интернете загружают ресурсы, например (Основано на window С чем вы столкнулись

script.js

является экземпляром

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="init.js"></script>
    <script type="text/javascript">
      MYLIBRARY.init(["firstValue", 2, "thirdValue"]);
    </script>
    <script src="script.js"></script>
  </head>

  <body>
    <h1>Hello !</h1>
  </body>    
</html>

plnkr . Надеюсь, это поможет! . Он включает интерфейс на основе Java, который определяет URL-адреса и упрощает доступ к ним. С чем вы столкнулись

var MYLIBRARY = MYLIBRARY || (function(){
    var _args = {}; // private

    return {
        init : function(Args) {
            _args = Args;
            // some other initialising
        },
        helloWorld : function(i) {
            return _args[i];
        }
    };
}());

В глобальной области видимости нет семантической разницы.

// Here you can use the values defined in the html as if it were a global variable
var a = "Hello World "   MYLIBRARY.helloWorld(2);

alert(a);

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

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

Всегда используйте замыкания и всегда переходите в глобальную область видимости, когда это абсолютно необходимо. В любом случае вы должны использовать асинхронную обработку событий для большей части вашего взаимодействия. a=0 Как заметил @AvianMoncellor, в IE есть ошибка с только объявляет глобальный для области видимости файла. Это проблема с пресловутым испорченным интерпретатором IE. Эта ошибка звучит знакомо, так что, вероятно, это правда.

Так что придерживайтесь

(function() {
   // do stuff locally

   // Hoist something to global scope
   window.someGlobal = someLocal
}());

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

Как упомянул @AvianMoncellor, есть ошибка IE, в которой var a = foo объявляет только глобальную область видимости файла. Это проблема пресловутого сломанного интерпретатора IE. Эта ошибка звучит знакомо, так что, вероятно, это правда.

Так что придерживайтесь window.globalName = someLocalpointer