Подтвердить что ты не робот

Объявление переменных без ключевого слова var

В w3schools написано:

Если вы объявляете переменную, не используя "var", переменная всегда становится GLOBAL.

Полезно ли объявлять глобальную переменную внутри функции? Я могу представить, чтобы объявить некоторые глобальные переменные в каком-то обработчике событий, но для чего это полезно? Лучшее использование ОЗУ?

4b9b3361

Ответ 1

Нет, никакой пользы от ОЗУ или чего-то в этом роде нет.

То, о чем говорит w3schools, я называю "Ужасом неявных глобалов". Рассмотрим эту функцию:

function foo() {
    var variable1, variable2;

    variable1 = 5;
    varaible2 = 6;
    return variable1 + variable2;
}

Кажется достаточно простым, но возвращает NaN, а не 11, из-за опечатки в varaible2 = 6; линия. И он создает глобальную переменную с именем typo'd:

function foo() {
    var variable1, variable2;

    variable1 = 5;
    varaible2 = 6;
    return variable1 + variable2;
}
console.log(foo());     // NaN
console.log(varaible2); // 6?!?!?!

Ответ 2

Побочные эффекты при запуске var

Это небольшое различие между подразумеваемыми глобалями и явно определенными. Разница заключается в способности деинфицировать эти переменные с помощью оператора delete:

• Глобалы, созданные с помощью var (созданные в программе вне любой функции) не может быть удалена.

• Подразумеваемые глобальные переменные, созданные без var (независимо от того, созданы ли внутри функций), могут быть удален.

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

// define three globals
var global_var = 1;
global_novar = 2; // antipattern
(function () {
   global_fromfunc = 3; // antipattern
}());
// attempt to delete
delete global_var; // false
delete global_novar; // true
delete global_fromfunc; // true
// test the deletion
typeof global_var; // "number"
typeof global_novar; // "undefined"
typeof global_fromfunc; // "undefined"

В строгом режиме ES5 назначаются необъявленные переменные (например, два антипаттерна в предыдущем фрагменте) выдает ошибку.

Шаблоны JavaScript, Стоян Стефанов (OReilly). Copyright 2010 Yahoo!, Inc., 9780596806750.

Ответ 3

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

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

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

Ответ 4

Иногда полезно создавать новые глобально доступные свойства внутри функций, которые впоследствии могут быть легко доступны путем ссылки на объект окна (все объявленные глобально свойства прикреплены к объекту окна).

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

Ответ 5

Основная проблема заключается в том, что кто-то еще может использовать глобальное имя с таким же именем.

Затем, когда вы измените значение глобального, вы перезапишите их значение.

Позже, когда глобальное использование будет использовано, оно будет загадочно изменено.

Ответ 6

Я бы сказал, что это может повредить вашей безопасности и даже стабильности вашего кода.

Как было упомянуто выше, вы можете ошибиться, просто неправильно написав ваши переменные, а решением является ключевое слово "use strict";
С объявленным этим ключевым словом вы получите ошибку: Uncaught ReferenceError: foo is not defined.

Это также относится к защищенному коду:
1. При написании защищенного кода мы не хотим, чтобы к нашим переменным обращался где-либо, кроме того места, где они были фактически объявлены. Не объявляйте глобальные переменные без необходимости.
2. Всегда внимательно читайте предупреждения и устраняйте их. Используйте "use strict"; , JSlint и другие инструменты, чтобы увидеть и устранить предупреждение, чтобы сделать ваш код лучше.

Ответ 7

Объявление переменной внутри функции без использования var, let или const не более полезно внутри функции, чем объявление этой переменной с помощью var, let или const. И, как отмечалось в предыдущих ответах на этот вопрос, локальные, неявные глобальные объявления функций могут быть запутанными и проблематичными вне области функции, в которой они были объявлены.

Я хотел бы поговорить с некоторыми тонкостями, которые отсутствуют в цитате w3schools и в предыдущих ответах на этот вопрос.

Прежде всего, если вы никогда не вызовете функцию, которая генерирует неявные глобальные переменные, вы не будете генерировать какие-либо неявные глобальные переменные. Это тонкое отличие от цитаты w3schools, поскольку она не соответствует разделу "всегда" в их утверждении.

function generateImplicitGlobals(){
  x = "x";
  window.y = "y";
}

// before calling the generateImplicitGlobals function, we can safely see that the a and b properties of the window object are both undefined:
console.log("before calling the generateImplicitGlobals function, properties x and y of the window object are: " + window.x + " and " + window.y);

// before calling the generateImplicitGlobals function, we can test for the existence of global variables a and b; note that we get errors instead of undefined for both.
try{
  console.log("before calling the generateImplicitGlobals function, x is: " + x);
}
catch(e){
  console.log("before calling the generateImplicitGlobals function, an attempt to reference some global variable a produces " + e);
}

try{
  console.log("before calling the generateImplicitGlobals function, y is: " + y);
}
catch(e){
  console.log("before calling the generateImplicitGlobals function, an attempt to reference the global variable b also produces " + e);
}