小编典典

如何取消设置 JavaScript 变量?

all

我在 JavaScript
中有一个全局变量(实际上是一个window属性,但我认为这并不重要),它已经由以前的脚本填充,但我不希望稍后运行另一个脚本来查看它的值或者它是甚至定义。

我已经提出some_var = undefined并且它可以用于测试目的,typeof some_var == "undefined"但我真的认为这不是正确的方法。

你怎么看?


阅读 118

收藏
2022-03-04

共1个答案

小编典典

操作员从对象中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 规范所称的“ VariableEnvironment ”中创建的,它附加到当前范围 -
这可能是在函数var内部使用的情况下的函数执行上下文(尽管它可能会变得有点复杂当您考虑时let)或在“全局”代码的情况下,
VariableEnvironment 附加到全局对象(通常window)。

VariableEnvironment 中的引用通常不可删除 - ECMAScript 10.5中详述的过程详细解释了这一点,但足以说明除非您的代码在eval上下文中执行(大多数基于浏览器的开发控制台使用),否则声明的变量var不能被删除。

2.不使用var

当试图在不使用var关键字的情况下为名称分配值时,JavaScript 会尝试在 ECMAScript 规范所称的“
LexicalEnvironment ”中定位命名引用,主要区别在于 LexicalEnvironment
是嵌套的——即 LexicalEnvironment 有一个父级 ( ECMAScript 规范称为“外部环境引用”),当 JavaScript 无法在
LexicalEnvironment 中找到引用时,它会在父 LexicalEnvironment
中查找(详见10.3.110.2.2.1)。顶层 LexicalEnvironment 是“
全局环境”

“,并且绑定到全局对象,因为它的引用是全局对象的属性。因此,如果您尝试访问未var在当前作用域或任何外部作用域中使用关键字声明的名称,JavaScript
最终将获取一个属性对象的window属性作为引用。正如我们之前所学的,对象的属性可以被删除。

笔记

  1. 重要的是要记住var声明是“提升的”——即它们总是被认为发生在它们所在范围的开头——尽管不是可以在var语句中完成的值初始化——它被留在原处. 所以在下面的代码中,a是来自 VariableEnvironment 而不是window属性的引用,它的值将10在代码的末尾:

    function test() { a = 5; var a = 10; }
    
  2. 上面的讨论是没有启用“严格模式”的情况。使用“严格模式”时查找规则有点不同,在没有“严格模式”的情况下解析为窗口属性的词法引用将在“严格模式”下引发“未声明的变量”错误。我真的不明白这是在哪里指定的,但它是浏览器的行为方式。

2022-03-04