Javascript 为什么Firebug允许删除其控制台中声明的全局变量?
我在一本书(JavaScript-权威指南第6版)中读到,使用Javascript 为什么Firebug允许删除其控制台中声明的全局变量?,javascript,Javascript,我在一本书(JavaScript-权威指南第6版)中读到,使用var关键字声明的全局变量不能使用delete关键字删除。但我可以在Firebug控制台中运行它 var a = 1; delete a;// should return false but returns true in firebug. 我不明白,为什么会这样 编辑 我的问题不是如何取消设置全局变量,而是如果您像我使用var关键字那样声明全局变量,它将创建全局对象的不可配置属性,而不能使用delete关键字删除该属性。但我可以在
var
关键字声明的全局变量不能使用delete
关键字删除。但我可以在Firebug控制台中运行它
var a = 1;
delete a;// should return false but returns true in firebug.
我不明白,为什么会这样
编辑
我的问题不是如何取消设置全局变量,而是如果您像我使用var
关键字那样声明全局变量,它将创建全局对象的不可配置属性,而不能使用delete
关键字删除该属性。但我可以在Firebug控制台中完成,这是不应该发生的 检查你的拼写
truevar != trueval
看来你犯了拼写错误
var trueval = 1;
delete truevar;//spelling mistake here
它会起作用,但从技术上讲它应该起作用
delete window.some_var;
当目标不是对象属性时,delete应该是no-op。e、 g
(function() {
var foo = 123;
delete foo; // wont do anything, foo is still 123
var bar = { foo: 123 };
delete bar.foo; // foo is gone
}());
但由于全局变量实际上是window对象的成员,所以它可以工作
当涉及到原型链时,使用delete会变得更复杂,因为它只从目标对象中删除属性,而不从原型中删除属性。e、 g
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.
所以要小心
编辑:我的答案是(见最后的“误解”)。该链接解释了所有血淋淋的细节,但总结是浏览器之间可能存在很大的差异,这取决于您要从中删除的对象<代码>删除对象。只要
对象!==窗口
。我仍然不会用它来删除用var
声明的变量,尽管在适当的情况下可以这样做。您不能删除全局变量,但您可以这样做
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.
更多参考
Firebug控制台中的代码使用
eval
执行。在eval代码中创建的变量绑定是可变的(这取决于尚未声明的变量),可以删除
见第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,则随后可能会删除绑定
正如@NagaJolokia指出的,
delete
在Firebug控制台中的行为不同,因为控制台使用eval()
来执行代码
如果在普通代码和eval()下测试delete
,则可以看到相同的效果。保存此页面并在开发人员控制台打开的情况下将其加载到任何浏览器中:
评估/删除测试
log('normalcode,a=1');
var a=1;
日志('a is',类型a,a);
控制台日志('window.a is',window.a的类型,window.a);
console.log('deleteaok',deletea);
log('delete window.a OK?',delete window.a);
log('a is now',a的类型,window.a);
console.log('window.a现在是',类型为window.a,window.a);
控制台日志(“”);
log('Eval code,b=1');
评估('var b=1;');
console.log('deletebok',deleteb);
log('b是now',类型为b,window.b);
代码将记录:
正常代码,a=1
a是1号
窗户。a是1号
删除一个好吗?假的
删除窗口。a确定吗?假的
a现在是第一位
窗口。a现在是1号
评估代码,b=1
删除b行吗?真的
b现在未定义
我还用相同的代码做了一个测试,准备运行。它产生与上面相同的输出。fiddle包括,因此您不需要打开开发人员控制台
有关更详细的解释,请参阅和。您是否意识到您有两个不同的变量trueval
与truevar
不同。可能是@DavidThomas的副本修复了它。@ZaheerAhmed和投票结束的人:这不是另一个问题的副本。这个问题问为什么Firebug会这样做。另一个问题及其答案根本没有讨论Firebug。OP是关于全局变量的,而不是其他对象的属性。这个复制粘贴的解释是不正确的。然而,这篇链接文章非常出色,并清楚地解释了正在发生的事情。这个答案与OP的问题并不相关:Firebug为什么会这样做@NagaJolokia给出了正确的答案:这是因为Firebug使用eval来执行代码。有关此问题的解释,请参阅链接文章的部分(而不是“误解”部分)。Downvoter,请阅读规范,并评论您为何否决,谢谢+1并同意,您的答案是正确的。为了帮助读者,我冒昧地复制了ECMAScript标准中引用的段落,并添加了表17中的相关条目。@MichaelGeary感谢您的改进!