在eval中使用var声明的全局变量可以被delete删除; 未使用var声明的全局变量可以使用delete进行删除

发布时间 2023-11-13 15:06:28作者: 龙陌

执行完如下程序后,所有能被访问到的变量包括()

var a = 1;
b = 2;
eval('var c = 3');
delete a;
delete b;
delete c;

A
a、b、c

B
a、c

C
a

D
c

在eval中使用var声明的全局变量可以被delete删除,所以变量c能删除成功,
除此之外,在其他情况下,使用var声明的全局变量或者局部变量一般是不能被delete删除的,所以变量a无法被删除,仍然可以访问到,
而未使用var声明的全局变量可以使用delete进行删除,所以无法访问到b。综上,只有变量a未被成功删除,可以访问得到

决定属性是否可以删除的关键在于属性描述属性值configurable是否是true,var定义的变量的configuarable的值是false,另外两个是true.
可以用
Object.getOwnPropertyDescriptor(window, 'a'),
Object.getOwnPropertyDescriptor(window, 'b'),
Object.getOwnPropertyDescriptor(window, 'c')验证

delete() delete 操作符用于删除对象的某个属性
var, let以及const创建的不可设置的属性不能被delete操作删除
不可配置属性configurable
当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认值为true。

ES6以后除了全局对象以外还维护了一个变量名列表,专门用来存储var,let,const声明的变量,并且约定了该列表里面的变量不能被delete删除,所以a变量无法被删除。
尽管var a =1;b =2 都是全局变量,都可以通过全局对象访问到。但b不是var声明的,可被delete删除,因此访问不了
eval中声明var变量是唯一一个被添加到变量名列表同时也可以被delete删除的特例,所以删除变量c有效