Javascript 未指定属性的变量是可删除的
我正在阅读JavascriptJavascript 未指定属性的变量是可删除的,javascript,properties,attributes,Javascript,Properties,Attributes,我正在阅读Javascriptdelete方法,并尝试了以下代码: function f(){ var x = "abcd"; console.log(delete x); //returns false, because x has DontDelete attribute y = "abcd"; console.log(delete y); //returns true, but I didn't explicitly assign y as a proper
delete
方法,并尝试了以下代码:
function f(){
var x = "abcd";
console.log(delete x); //returns false, because x has DontDelete attribute
y = "abcd";
console.log(delete y); //returns true, but I didn't explicitly assign y as a property
}
这很奇怪,因为我没有为y
使用属性分配(如:window.y=“abcd”
),这篇文章是如何使属性删除的
为什么y
没有DontDelete
属性
更新:
在下面的回答中,声称y是可删除的,仅仅因为它是窗口
对象的属性。事实并非如此。考虑下面的片段:
function f() {
var functionx = "abcd";
console.log(delete functionx); //returns false, because x has DontDelete attribute
functiony = "abcd";
console.log(delete functiony); //returns true, but I didn't explicitly assign functiony as a property to the window
}
//take 1
var globalx = "abcd";
console.log(this.globalx);//to prove x is a property of the global
console.log(delete globalx);//fails, even though x is a property of the window
//take 2
this.globaly = "abcd";
console.log(this.globaly);//to prove y is a property of the global
console.log(delete globaly);//succeeds, because I used property assignment
f();
在take 1中,globalx
是窗口的一个属性,但它仍然是不可删除的。delete
是否成功的标准不是该变量是否是某个对象的属性(始终为true),而是该属性是否设置了DontDelete
属性。delete x
无效,因为它不解析为任何对象属性
y
解析为窗口
对象的属性
:
删除表达式
表达式应计算为属性引用的位置
JavaScript中的变量。当您省略var
时,解释器开始查找定义给定变量的最近范围。如果找不到给定的变量
这正是这里发生的事情:
- 变量
y
被引用并分配了一个新值(abcd
)
- Var
y
未在任何地方定义→ 将创建新的全局属性y
,并为其赋值(有效地window.y=“abcd”
)
- 因此,
y
成为可以删除的全局对象的属性
下面是第二个示例的扩展版本:
window.y = "abcd";
console.log(delete window.y);
现在很明显发生了什么
如果不使用var
关键字,解释器将假定变量是全局对象的属性(通常是窗口
),如中所示。请注意,在全局范围中,此
与窗口
对象相同
回复:更新:
在函数外部,用var
声明的变量定义为全局对象的不可配置属性。这在中有详细说明,其中说明:
在函数外部使用var
是可选的;将值赋给未声明的变量会隐式地将其声明为全局变量(也是全局对象的属性)。区别在于声明的变量是全局对象的不可配置属性,而未声明的是可配置属性
在函数中声明变量不会将其指定给全局属性,而是指定给局部变量
这解释了在全局范围内定义变量时所看到的行为。当前执行上下文的变量对象的属性不是吗?@Asad这是一个实现细节,从js的角度来看,它只是一个变量。它不是用户代码可以访问的任何对象的属性。我有点了解它,但为什么运行var x=“abcd”;console.log(删除x)全局上下文日志中的代码>错误?当我使用var x时,x仍然是窗口对象的属性。为什么不可删除?@Asad使用var
创建的全局变量具有DontDelete
(即configurable===false
…如果执行window.x=“abcd”
,它应该可以工作。当我看到时,我肯定没有得到你描述的结果。我认为给出的答案仍然有效。@KendallFrey你需要将脚本放在正文中,而不是在onLoad事件中。这是一个更新的提琴:另外,我不小心错过了localx
旁边的var
,谢谢你的回答。我的问题是并非全局对象的所有属性都可以删除。请参阅我的更新。不,如果没有var
,则会搜索父作用域-这与此
无关。如果找不到标识符,则会将其视为全局对象的全局变量/属性。@Bergi感谢您指出这一点。我已更新了回答。