我在 JavaScript 中有一个全局变量(实际上是一个window
属性,但我认为这并不重要),它已经由以前的脚本填充,但我不希望稍后运行另一个脚本来查看它的值,或者甚至定义它。
我已经把some_var = undefined
它用于测试目的typeof some_var == "undefined"
但我真的不认为这是正确的做法。
你怎么认为?
The delete
运算符从对象中删除属性。它无法删除变量。所以问题的答案取决于全局变量或属性是如何定义的。
(1) 如果创建的是var
,无法删除。
例如:
var g_a = 1; //create with var, g_a is a variable
delete g_a; //return false
console.log(g_a); //g_a is still 1
(2) 如果创建时没有var
,可以删除。
g_b = 1; //create without var, g_b is a property
delete g_b; //return true
console.log(g_b); //error, g_b is not defined
技术说明
1. 使用var
在这种情况下参考g_a
是按照 ECMAScript 规范所称的“可变环境" 附加到当前作用域 - 在使用的情况下,这可能是函数执行上下文var
在函数内部(尽管当您考虑时可能会变得更复杂一些)let
)或在“全局”代码的情况下可变环境附加到全局对象(通常window
).
参考文献中可变环境通常不可删除 - 详细过程见ECMAScript 10.5详细解释了这一点,但足以说明,除非您的代码在eval
上下文(大多数基于浏览器的开发控制台使用),然后使用声明的变量var
无法删除。
2. 不使用var
当尝试在不使用var
关键字,JavaScript 尝试在 ECMAScript 规范中调用的内容中查找命名引用“词汇环境”,主要区别在于词汇环境s 是嵌套的 - 即词汇环境有一个父级(ECMAScript 规范称之为“外部环境引用”),并且当 JavaScript 无法在父级中找到引用时词汇环境,它看起来在父级中词汇环境(详细信息见10.3.1 and 10.2.2.1)。顶层词汇环境是个 ”全球环境“,并且它绑定到全局对象,因为它的引用是全局对象的属性。因此,如果您尝试访问未使用声明的名称var
当前作用域或任何外部作用域中的关键字,JavaScript 最终将获取该属性window
对象作为该引用。正如我们之前所了解的,对象的属性可以被删除。
Notes
-
重要的是要记住var
声明是“提升的” - 即它们总是被认为发生在它们所在范围的开头 - 尽管不是可以在 a 中完成的值初始化var
声明 - 留在原处。所以在下面的代码中,a
是来自的参考可变环境而不是window
财产及其价值将是10
在代码末尾:
function test() { a = 5; var a = 10; }
-
上述讨论是在未启用“严格模式”时的情况。使用“严格模式”时,查找规则有点不同,在没有“严格模式”的情况下解析为窗口属性的词法引用将在“严格模式”下引发“未声明的变量”错误。我不太明白这是在哪里指定的,但它是浏览器的行为方式。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)