Javascript 关于eval语句构造和删除

Javascript 关于eval语句构造和删除,javascript,google-chrome,Javascript,Google Chrome,如果我在GoogleChrome控制台中运行以下代码,我会得到以下结果 var x = 1; alert(delete x); // false 为什么在第一个示例中不删除变量,而在第二个示例中删除变量?: delete仅对对象的属性有效。它没有效果 关于变量或函数名 提供的示例与您的类似 x = 42; // creates the property x on the global object var y = 43; // declares a new vari

如果我在GoogleChrome控制台中运行以下代码,我会得到以下结果

var x = 1;

alert(delete x); // false

为什么在第一个示例中不删除变量,而在第二个示例中删除变量?

delete
仅对对象的属性有效。它没有效果 关于变量或函数名

提供的示例与您的类似

x = 42;         // creates the property x on the global object
var y = 43;     // declares a new variable, y

delete x;       // returns true  (x is a property of the global object and can be deleted)
delete y;       // returns false (delete doesn't affect variable names)
那么,为什么
alert(删除y)工作?我不能确定确切的答案,但基本上你不能依赖评估的范围

我认为
eval('var y=2')
没有被声明为变量,并且被视为属性,但是除了测试结果之外,我还没有找到其他证据。我将继续研究,看看是否找到确切的原因

关于
eval
weirdness的其他文章:


编辑0

根据@Xavier Holt的评论,我查找了有关
eval
的提升和范围。有以下内容:

eval可以捕获分配,但不能捕获var声明

eval'd vars正常提升,因此eval可能捕获类似的任务 与:

function f() {   {
    let x = "inner";
    eval("var x = 'outer'");
    print(x); // "outer"   } 
}

如果我读对了,那么我先前的假设是正确的
eval()
不会通过声明变量来计算
var
声明。它必须创建一个属性或被视为一个属性,才能使
删除
正常工作。

附加问题:您为什么需要这个?我无法提供任何技术细节,但我怀疑这与JavaScript的“”行为有关。本质上,变量定义为
var foo得到特殊处理,因为JS引擎在函数运行之前就知道它们在那里。使用
eval
声明的变量无法识别,因此无法得到特殊处理。您已经阅读了吗?我同意您的假设。在执行函数时会创建一个活动对象。AO包含作为键值对的每个变量声明。这是在函数运行任何代码之前完成的。因此,eval的声明可能不会修改AO,而是通过添加一个新属性来实现。
在eval上下文中创建的变量将其[[DontDelete]]属性设置为false(或等效的ECMA 5)
引用自
function f() {   {
    let x = "inner";
    eval("var x = 'outer'");
    print(x); // "outer"   } 
}