Нет, нет никакой выгоды от оперативной памяти или чего-то в этом роде.
То, о чем говорит w3schools, я называю Ужасом. неявных глобальных переменных. Рассмотрим эту функцию:
function foo() {
var variable1, variable2;
variable1 = 5;
varaible2 = 6;
return variable1 + variable2;
}
Выглядит достаточно просто, но возвращает NaN, а не 11 из-за опечатки в строке varaible2 = 6;. И он создает глобальную переменную с именем с опечаткой:
function foo() {
var variable1, variable2;
variable1 = 5;
varaible2 = 6;
return variable1 + variable2;
}
console.log(foo()); // NaN
console.log(varaible2); // 6?!?!?!
Это связано с тем, что функция присваивается varaible2 (обратите внимание на опечатку), но varaible2 нигде не объявлено. Благодаря механике цепочки областей видимости в JavaScript это приводит к неявному присвоению (новому) свойству глобального объекта (к которому вы можете получить доступ как window в браузерах).
Это просто особенность свободного режима JavaScript, присвоение полностью необъявленного идентификатора не является ошибкой; вместо этого он правильно создает глобальный объект, а свойства глобального объекта являются глобальными переменными. (Вплоть до ES5 все глобальные переменные были свойствами глобального объекта. Однако начиная с ES2015 был добавлен новый тип глобальных переменных, который не является свойством глобального объекта. Global-scope let, const и class создают новые какая-то глобальная)
Мой пример — опечатка, но вы, конечно, могли бы сделать это специально, если бы захотели. В конце концов, это четко определенная часть языка. Так:
myNewGlobal = 42;
... везде, где не объявлено myNewGlobal, будет создан новый глобальный.
Но я настоятельно рекомендую никогда не делать это специально: это затрудняет чтение и поддержку кода, и этот код будет несовместим с модулями JavaScript, когда они станут более распространенными и широко распространенными. Если вам действительно нужно создать глобальную переменную внутри функции во время выполнения (уже красный флаг, но для этого есть веские причины), сделайте это явно, назначив свойство на window (или что-то еще, что ссылается на глобальный объект в вашем среде; это window в браузерах):
window.myNewGlobal = 42;
На самом деле, я бы предложил использовать строгий режим ES5< /эм>а>. Строгий режим делает присвоение необъявленного идентификатора ошибкой, а не молча создает глобальный идентификатор. Если бы мы использовали строгий режим, проблему с foo выше было бы намного проще диагностировать:
"use strict"; // Turns on strict mode for this compilation unit
function foo() {
var variable1, variable2;
variable1 = 5;
varaible2 = 6; // <=== ReferenceError
return variable1 + variable2;
}
console.log(foo());
Несколько тангенциально, но в целом я бы рекомендовал избегать глобальных переменных, где это возможно. Глобальное пространство имен уже очень и очень загромождено в браузерах. Браузер создает глобал для каждого элемента в DOM с id, для большинства элементов с name и имеет несколько собственных предопределенных глобалов (например, title), которые могут легко конфликтовать с вашим кодом.
Вместо этого просто определите себе хорошую функцию области видимости и поместите в нее свои символы:
(function() {
var your, symbols, here, if_they_need, to_be_shared, amongst_functions;
function doSomething() {
}
function doSomethingElse() {
}
})();
И если вы это сделаете, вы можете включить строгий режим:
(function() {
"use strict";
var your, symbols, here, if_they_need, to_be_shared, amongst_functions;
function doSomething() {
}
function doSomethingElse() {
}
})();
... который, как уже упоминалось, имеет то преимущество, что присваивания необъявленным идентификаторам превращаются в ошибки (вместе с другие полезные вещи).
Обратите внимание, что в модуле JavaScript (добавленном в ES2015, но только сейчас начинающем находить свой путь в дикой природе) строгий режим включен по умолчанию. (Это также относится к определениям class, также новым в ES2015.)
person
T.J. Crowder
schedule
31.07.2011