无法理解在JavaScript中删除vars的行为

时间:2014-01-15 10:13:32

标签: javascript variables

问题在于:

var x = 5;
window.x === x // true. x, as it seems, is a property of window
delete x; // false
delete window.x; // false;

BUT

window.x = 5;
delete window.x; // true

window.x = 5;
delete x; // true

这种行为的解释是什么?

3 个答案:

答案 0 :(得分:4)

基本上,原因是声明的变量是使用内部DontDelete属性创建的,而通过赋值创建的属性则不是。

以下是解释deleteUnderstanding delete

内部细节的精彩文章
  

当声明的变量和函数成为变量的属性时   object - 激活对象(用于功能代码)或全局   对象(对于全局代码),这些属性是使用DontDelete创建的   属性。但是,任何显式(或隐式)属性赋值   创建没有DontDelete属性的属性。这是必要的   为什么我们可以删除一些属性,而不是其他属性:

答案 1 :(得分:2)

您只能将delete用于删除对象,对象属性或数组元素。

  

删除 表达

如果无法表示 表达式 ,则

delete将无效    作为财产。因此delete可以删除全局变量,但不能删除var所引用的变量。

所以,让我解释一下:

var x = 5;

您可以通过var创建全局范围内的变量,而不是window对象的属性。这个var只链接到window.x.然后你比较window.x === x它将返回true。但是:

delete x; // deleting variable, not property, return false
delete window.x; // resolve link to x and also deleting variable, not property, return false

<强> BUT

window.x = 5;//add property
delete window.x; // can delete property, return true

window.x = 5;//add property
delete x; //resolve x. it's a propery of window, return true

及更早

ECMAScript 262/3中,因为@Peter解释可用DontDelete标志。但在ECMAScript 262/5.1严格模式下,删除受Configurable标志:

的限制
  

在严格模式代码中发生删除操作符时,出现SyntaxError   如果其UnaryExpression是对a的直接引用,则抛出异常   变量,函数参数或函数名称。另外,如果一个   删除操作符发生在严格模式代码和属性中   deleted具有属性{[[Configurable]]:false},一个TypeError   抛出异常。

答案 2 :(得分:1)

这就是我理解的:

在全局范围内声明的

var x = 5;会创建新的window属性x

window.x = 5;声明(whereever)也会创建新的窗口属性x。这就是window.x === x为您提供true的原因。

不同之处在于,javascript默认根据(上面两个中的一个)的方式为x属性设置不同的描述符。

var x = 5等于:

Object.defineProperty(window,'x',{
  value: 5,
  writable: true,
  enumerable: true,
  configurable: false
});

window.x = 5等于:

Object.defineProperty(window,'x',{
  value: 5,
  writable: true,
  enumerable: true,
  configurable: true
});

configurable描述符(如果false)禁止delete该属性。 我们可以假设,当我们使用Object.defineProperty关键字以简单的方式声明变量或没有(自动分配给var)时,javascript使用window具有不同的描述符设置。 。 您只需检查:

var x = 5;
window.y = 5;

console.log(Object.getOwnPropertyDescriptor(window,'x')); //configurable:false
console.log(Object.getOwnPropertyDescriptor(window,'y')); //configurable:true