Влияние объявленных и необъявленных переменных

В чем основное различие между объявленными и необъявленными переменными JavaScript, поскольку оператор удаления не работает с объявленными переменными?

 var y = 43;     // declares a new variable
 x = 42;

 delete x;       // returns true  (x is a property of the global object and can be deleted)
 delete y;       // returns false (delete doesn't affect variable names) 

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

4 ответа

Решение

Объявленные и необъявленные глобальные переменные

Механизм их хранения и доступа к ним одинаков, но в некоторых случаях JavaScript обрабатывает их по-разному в зависимости от значения configurable атрибут (описан ниже). При регулярном использовании они должны вести себя одинаково.

Оба существуют в глобальном объекте

Ниже приведены некоторые сравнения объявленных и необъявленных глобальных переменных.

var declared = 1;  // Explicit global variable (new variable)
undeclared   = 1;  // Implicit global variable (property of default global object)

window.hasOwnProperty('declared')    // true
window.hasOwnProperty('undeclared')  // true

window.propertyIsEnumerable('declared')    // true
window.propertyIsEnumerable('undeclared')  // true

window.declared     // 1
window.undeclared   // 1

window.declared   = 2;
window.undeclared = 2;

declared     // 2
undeclared   // 2

delete declared     // false
delete undeclared   // true
delete undeclared   // true (same result if delete it again)

delete window.declared     // false
delete window.undeclared   // true (same result if delete it yet again)
delete window.undeclared   // true (still true)

Как объявленные, так и необъявленные глобальные переменные являются свойствами window объект (глобальный объект по умолчанию). Ни один из них не наследуется от другого объекта через цепочку прототипов. Они оба существуют прямо в window объект (с window.hasOwnProperty возвращается true для обоих).

Настраиваемый атрибут

Для объявленных глобальных переменных configurable атрибут false, Для необъявленных глобальных переменных это true, Значение configurable атрибут может быть получен с помощью getOwnPropertyDescriptor метод, как показано ниже.

var declared = 1;
undeclared = 1;

(Object.getOwnPropertyDescriptor(window, 'declared')).configurable     // false
(Object.getOwnPropertyDescriptor(window, 'undeclared')).configurable   // true

Если configurable атрибут свойства имеет значение true, атрибуты свойства могут быть изменены с помощью defineProperty метод, и свойство может быть удалено с помощью delete оператор. В противном случае атрибуты не могут быть изменены, и свойство не может быть удалено таким образом.

В нестрогом режиме delete оператор возвращает true если свойство настраивается и возвращает false если это не настраивается.

Резюме

Объявленная глобальная переменная

  • Свойство глобального объекта по умолчанию (window)
  • Атрибуты свойства не могут быть изменены.
  • Не может быть удалено с помощью delete оператор

Необъявленная глобальная переменная

  • Свойство глобального объекта по умолчанию (window)
  • Атрибуты свойства могут быть изменены.
  • Можно удалить с помощью delete оператор

Смотрите также

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

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

var y = 43;
delete y;         //returns false because it is has a DontDelete attribute

Принимая во внимание, что необъявленное назначение не устанавливает никаких атрибутов, таких как DontDelete. Поэтому, когда мы применяем оператор удаления к этой необъявленной переменной, она возвращает true.

x = 42;
delete x;        //returns true because it doesn't have a DontDelete attribute

Разница между назначением свойства и объявлением переменной - последний устанавливает DontDelete, а первый - нет. Вот почему незадекларированное присваивание создает удаляемое свойство.

Ссылка на то, как именно работает оператор удаления

delete действует только на свойства объекта. Это не влияет на имена переменных или функций.

В вашем случае х = 42; объявляет переменную X и делает ее свойством объекта Global. Так что возвращается правда.

И у у = 43; объявляет глобальную переменную, которая не является частью какого-либо объекта, поэтому возвращает false.

Другие вопросы по тегам