声明和未声明变量的影响

时间:2013-04-13 08:34:02

标签: javascript variables global-variables variable-declaration

JavaScript声明和未声明变量之间的主要区别是什么? delete运算符不适用于声明的变量吗?

 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) 

为什么会这样?全局声明的变量也是window对象的属性,为什么不能删除呢?

4 个答案:

答案 0 :(得分:26)

声明和未声明的全局变量

存储和访问它们的机制是相同的,但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。可以使用getOwnPropertyDescriptor方法检索configurable属性的值,如下所示。

var declared = 1;
undeclared = 1;

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

如果属性的configurable属性为true,则可以使用defineProperty方法更改属性的属性,并且可以使用delete运算符删除属性。否则,无法更改属性,并且无法以此方式删除属性。

non-strict mode中,如果属性是可配置的,delete运算符将返回true,如果属性不可配置,则返回false

摘要

声明的全局变量

  • 是默认全局对象(window
  • 的属性
  • 无法
  • 更改属性属性。
  • 无法使用delete运算符
  • 删除

未声明的全局变量

  • 是默认全局对象(window
  • 的属性
  • 属性可以更改。
  • 可以使用delete运算符
  • 删除

另见

答案 1 :(得分:1)

主要区别在于您在函数内声明变量。如果在函数内声明变量时使用var,则该变量将成为局部变量。但是,如果您不使用var,那么无论您在何处声明它(在函数内部或外部),该变量都将成为全局变量。

答案 2 :(得分:1)

当通过 JavaScript 中的变量声明创建任何变量时,这些属性是使用“ DontDelete ”属性创建的,这基本上意味着您创建的变量无法使用“删除”删除“表达式。默认情况下,所有函数,参数和函数参数都是使用此DontDelete属性创建的。您可以将DontDelete视为旗帜。

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

而未声明的作业不会设置任何属性,例如 DontDelete 。因此,当我们对此未声明的变量应用 delete 运算符时,它将返回true。

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

属性赋值和变量声明之间的区别 - 后者设置DontDelete,而前者不设置。这就是为什么未声明的赋值会创建一个可删除的属性。

Link on how exactly delete operator works

答案 3 :(得分:0)

delete仅对对象的属性有效。它对变量或函数名称没有影响。

在你的情况下x = 42;声明变量X并使其成为Global对象的属性。所以它返回true。

并且var y = 43;声明一个全局变量,它不是任何对象的一部分,因此返回false。