为什么javascript在删除时区分有或没有声明的赋值?

yua*_*uan 6 javascript

在全局上下文中执行以下代码:

var x = 1;
y = 1
delete x //false
delete y //true
Run Code Online (Sandbox Code Playgroud)

这两个xy是全局对象的属性.为什么javascript必须在某种程度上区分它们?


这很容易按套路accoring到ES5标准delete运营商对象的内部方法[[delete]].

更明确的问题是他们为什么采用不同的[[configurable]]属性?

Vis*_*ons 5

看看在第二个答案此相关的问题kangax.

var x = 1声明当前作用域中的变量x(也称为执行上下文).如果声明出现在函数中 - 声明了局部变量; 如果它在全局范围内 - 声明全局变量.

另一方面,x = 1仅仅是属性赋值.它首先尝试针对作用域链解析x.如果它在该范围链中的任何位置找到它,它将执行赋值; 如果它没有找到x,那么它只在全局对象(它是作用域链中的顶级对象)上创建x属性.

现在,请注意它没有声明全局变量,它会创建一个全局属性.

两者之间的区别是微妙的,可能会令人困惑,除非您了解变量声明也创建属性(仅在变量对象上)并且Javascript中的每个属性(即,ECMAScript)都有某些描述其属性的标志 - ReadOnly,DontEnum和DontDelete .

由于变量声明使用DontDelete标志创建属性,因此var x = 1和x = 1(在全局范围内执行时)之间的差异是前一个 - 变量声明 - 创建DontDelete'able属性,后者不创建.因此,可以从全局对象中删除通过此隐式赋值创建的属性,而前者 - 通过变量声明创建的属性 - 不能.