简体   繁体   English

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

[英]Can't understand the behavior of deleting vars in JavaScript

Here is the issue: 这是问题:

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

AND

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

What is the explanation for such behavior? 这种行为的解释是什么?

Essentially the reason is that declared variables are created with an internal DontDelete attribute, while properties created via assignment are not. 基本上原因是声明的变量是使用内部DontDelete属性创建的,而通过赋值创建的属性则不是。

Here is great article explaining the inner details of delete : Understanding delete 这是一篇很棒的文章,解释了delete的内部细节: 了解删除

When declared variables and functions become properties of a Variable object — either Activation object (for Function code), or Global object (for Global code), these properties are created with DontDelete attribute. 当声明的变量和函数成为Variable对象的属性 - Activation对象(对于Function代码)或Global对象(对于Global代码)时,这些属性是使用DontDelete属性创建的。 However, any explicit (or implicit) property assignment creates property without DontDelete attribute. 但是,任何显式(或隐式)属性赋值都会创建没有DontDelete属性的属性。 And this is essentialy why we can delete some properties, but not others: 这是必要的,为什么我们可以删除一些属性,而不是其他属性:

You can use delete only for deleting objects, object properties or array element. 您只能将delete用于删除对象,对象属性或数组元素。

delete expression 删除表达式

delete will be not working if expression can't be represented as property. 如果表达式不能表示为属性,则delete将无效。 So delete can remove global variable, but not variables inited by var . 因此delete可以删除全局变量,但不能delete var引用的变量。

So, let me explain: 那么,让我解释一下:

var x = 5;

You create variable in global scope by var, not property of window object. 您可以通过var创建全局范围内的变量,而不是window对象的属性。 This var is just linked to window.x. 这个var只链接到window.x. And then you compare window.x === x it will return true. 然后你比较window.x === x它将返回true。 But: 但:

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

AND

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

and older 和更老的

In ECMAScript 262/3 as @Peter explain is available DontDelete flag. ECMAScript 262/3中,@ Peter解释了DontDelete标志。 But in ECMAScript 262/5.1 in strict mode deleting is regulated by Configurable flag: 但在严格模式的ECMAScript 262 / 5.1中,删除由可Configurable标志调节:

When a delete operator occurs within strict mode code, a SyntaxError exception is thrown if its UnaryExpression is a direct reference to a variable, function argument, or function name. 当严格模式代码中出现删除操作符时,如果其UnaryExpression是对变量,函数参数或函数名称的直接引用,则抛出SyntaxError异常。 In addition, if a delete operator occurs within strict mode code and the property to be deleted has the attribute { [[Configurable]]: false }, a TypeError exception is thrown. 此外,如果删除操作符出现在严格模式代码中,并且要删除的属性具有属性{[[Configurable]]:false},则抛出TypeError异常。

This is how I understand that: 这就是我的理解:

var x = 5; declared in the global scope creates the new window property x . 在全局范围内声明,创建新的window属性x

window.x = 5; declared (whereever) creates the new window property x as well. 声明(whereever)也创建新的窗口属性x That's why window.x === x gives you true . 这就是为什么window.x === x给你的true

The difference is that javascript by default sets different descriptors for x property according to the way (one of two above) it is declared. 不同之处在于,javascript默认根据声明的方式(上面两个中的一个)x属性设置不同的描述符。

var x = 5 is equal to: var x = 5等于:

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

while window.x = 5 is equal to: window.x = 5等于:

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

The configurable descriptor, if false , forbides to delete the property. configurable描述符(如果为false )禁止delete该属性。 We can assume, that javascript use Object.defineProperty with different descriptor settings under the hood when we declare variables in a simple way with var keyword or without it (automatically assigned to window ) . 我们可以假设,当我们使用var关键字或没有它(自动分配给window以简单的方式声明变量时,javascript使用具有不同描述符设置的Object.defineProperty You can simply check that: 你可以简单地检查:

var x = 5;
window.y = 5;

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM