[英]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.