3

我在一本书(JavaScript - 权威指南第 6 版)中读到,使用关键字声明的全局变量var不能使用delete关键字删除。但我可以在 Firebug 控制台中运行它。

var a = 1;
delete a;// should return false but returns true in firebug.

我无法弄清楚,为什么会这样?

编辑

我的问题不是关于如何取消设置全局变量,而是关于如果您像我使用var关键字一样声明全局变量,它会创建全局对象的不可配置属性,该属性无法使用delete关键字删除。但我可以在 Firebug 控制台中做到这一点,这不应该发生。

4

6 回答 6

2

这里有详细解答

它会起作用,但从技术上讲,它应该是

delete window.some_var; 

当目标不是对象属性时,删除应该是空操作。例如,

(function() {
   var foo = 123;
   delete foo; // wont do anything, foo is still 123
   var bar = { foo: 123 };
   delete bar.foo; // foo is gone
}());

但是由于全局变量实际上是窗口对象的成员,所以它可以工作。

当涉及原型链时,使用 delete 变得更加复杂,因为它只从目标对象中删除属性,而不是原型。例如,

function Foo() {}
Foo.prototype = { bar: 123 };
var foo = new Foo();
// foo.bar is 123
foo.bar = 456;
// foo.bar is now 456
delete foo.bar;
// foo.bar is 123 again.

所以要小心。

编辑:我的回答有些不准确(见最后的“误解”)。该链接解释了所有血淋淋的细节,但总结是浏览器之间可能存在很大差异,具体取决于您要从中删除的对象。delete object.someProp一般只要object !== window. 我仍然不会使用它来删除声明的变量,var尽管您可以在适当的情况下。

于 2013-07-05T13:10:02.250 回答
2

Firebug 控制台中的代码使用eval. 并且在 eval 代码中创建的变量绑定是可变的(这取决于尚未声明的变量)并且可以删除。

请参阅ECMAScript 语言规范,第 10.5 节第 2 项:

如果代码是 eval 代码,则令可配置绑定为,否则令可配置绑定

和第 8.ci 项:

调用env的 CreateMutableBinding 具体方法,传递dnconfigureBindings作为参数。

连同第 10.2.1 节中的表 17:

CreateMutableBinding(N, D)
在环境记录中创建一个新的可变绑定。字符串值N是绑定名称的文本。如果可选的布尔参数D,则绑定可能随后被删除。

于 2013-07-05T15:34:24.853 回答
2

正如@NagaJolokia 指出的那样,delete在 Firebug 控制台中的行为不同,因为控制台eval()用于执行代码。

如果您delete在普通代码和eval(). 保存此页面并在打开开发者控制台的任何浏览器中加载它:

<!DOCTYPE html>
<html>
<head>
    <title>Eval/Delete Test</title>
    <script>
        console.log( 'Normal code, a = 1' );
        var a = 1;
        console.log( 'a is', typeof a, a );
        console.log( 'window.a is', typeof window.a, window.a );
        console.log( 'delete a OK?', delete a );
        console.log( 'delete window.a OK?', delete window.a );
        console.log( 'a is now', typeof a, window.a );
        console.log( 'window.a is now', typeof window.a, window.a );
        console.log( ' ' );
        console.log( 'Eval code, b = 1' );
        eval( 'var b = 1;' );
        console.log( 'delete b OK?', delete b );
        console.log( 'b is now', typeof b, window.b );
    </script>
</head>
<body>
</body>
</html>

代码将记录:

Normal code, a = 1
a is number 1
window.a is number 1
delete a OK? false
delete window.a OK? false
a is now number 1
window.a is now number 1

Eval code, b = 1
delete b OK? true
b is now undefined undefined

我还用准备运行的相同代码做了一个小提琴。它产生与上面相同的输出。小提琴包括Firebug Lite,因此您无需打开开发者控制台。

有关更详尽的解释,请参阅NagaJolokia 的回答和本文的Firebug 混淆部分

于 2013-07-06T08:30:45.173 回答
0

检查你的拼写

truevar != trueval
于 2013-07-05T13:08:51.110 回答
0

好像是你拼写错误

var trueval = 1;
delete truevar;//spelling mistake here
于 2013-07-05T13:09:59.427 回答
0

你不能删除全局变量,但你这样做

function Foo() {}

Foo.prototype = { bar: 123 };

var foo = new Foo();

// foo.bar is 123

foo.bar = 456;

// foo.bar is now 456

delete foo.bar;
// foo.bar is 123 again.

有关更多参考 如何取消设置 JavaScript 变量?

http://perfectkills.com/understanding-delete/

于 2013-07-05T13:10:08.130 回答