为什么Firebug允许删除在其控制台中声明的全局变量?

时间:2013-07-05 13:06:41

标签: javascript

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

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

我无法理解,为什么会发生这种情况?

修改

我的问题不是关于如何取消设置全局变量,而是关于如果使用var关键字声明全局变量,它会创建全局对象的不可配置属性,使用{无法删除{1}}关键字。但我能够在Firebug控制台中完成,这不应该发生。

6 个答案:

答案 0 :(得分:2)

Here is detailed answer

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

delete window.some_var; 
当目标不是对象属性时,

delete应该是无操作。如,

(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.

所以要小心。

编辑:我的回答是somewhat inaccurate(最后请参阅“误解”)。该链接解释了所有血腥细节,但摘要是浏览器之间可能存在很大差异,具体取决于您要删除的对象。只要delete object.somePropobject !== window通常应该是安全的。我仍然不会用它来删除用var声明的变量,尽管你可以在适当的情况下。

答案 1 :(得分:2)

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

请参阅ECMAScript Language Specification,第10.5节第2项:

  

如果代码是eval代码,那么让 configurableBindings true 否则让 configurableBindings false

和项目8.c.i。:

  

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

以及第10.2.1节中的表17:

  

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

答案 2 :(得分: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

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

有关更全面的说明,请参阅NagaJolokia's answerFirebug confusion section of this article

答案 3 :(得分:0)

检查拼写

truevar != trueval

答案 4 :(得分:0)

似乎你拼错了

var trueval = 1;
delete truevar;//spelling mistake here

答案 5 :(得分: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.

供更多参考 How to unset a JavaScript variable?

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