【问题标题】:Can the "let" keyword be used in JavaScript to avoid global-scoped variables?可以在 JavaScript 中使用“let”关键字来避免全局范围的变量吗?
【发布时间】:2016-07-20 12:44:10
【问题描述】:

我正在用 JavaScript 进行测试,我注意到使用 let 关键字就像

let variable = "I am a variable";
console.log(window.variable);

做了not add a variable property to the window object。这是否意味着它不存在于全局范围内?

我可以声明变量而不必在函数或 IIFE 中限定它们吗?

我确实搜索过这个但找不到任何东西。每个人都说要使用像{}() 这样的函数,或者只是访问一个包含代码的唯一全局变量,但是看到这个让我想知道它是否可以用于避免这些事情。

【问题讨论】:

  • 如果问题是:“顶级 lets 是否可以替代 IIFE 和函数的词法范围提供的封装?”那么我认为答案将是一个响亮的不。 ES2015 替代全局命名空间对象和 IIFE 的许多当前用途是模块。

标签: javascript scope ecmascript-6


【解决方案1】:

let 语句不能用于按照您建议的方式避免全局变量。顶级的let 语句仍会在全局范围内创建变量,只是不会将它们创建为“全局对象”的属性(通常是window)。

<script>
  'use strict';
  let fromLet = 'from let';
  var fromVar = 'from var';
</script>

<script>
  console.log(fromLet);        // 'from let'
  console.log(fromVar);        // 'from var'
  console.log(window.fromLet); // undefined
  console.log(window.fromVar); // 'from var'
</script>

此行为主要在 Section 8.1.1.4: Global Environment Records of the ECMAScript 6 specification 中描述。它的要点是有一个单一的全局范围/命名空间,但它的值可以记录在两个不同的地方。全局内置函数、function 声明、var 声明和 function*(生成器)声明被记录为全局对象的属性,而其他所有内容都是全局的(来自 let、const、class、和其他新结构)存储在内部“环境记录”中,该记录不会在运行时作为对象公开。

如果您想深入了解细节,可以从以下相关摘录开始。

全局环境记录用于表示由在公共Realm (8.2) 中处理的所有 ECMAScript Script 元素共享的最外层范围。全局 Environment Record 为内置全局变量 (clause 18)、全局对象的属性以及在 Script13.2.8、13.2.10) 提供绑定/em>。

可以直接在全局对象上创建属性。因此,全局 Environment Record 的对象 Environment Record 组件可能包含由 FunctionDeclaration、GeneratorDeclaration 或 VariableDeclaration 声明显式创建的绑定和绑定作为全局对象的属性隐式创建。为了识别使用声明显式创建的绑定,全局 Environment Record 维护使用其 CreateGlobalVarBindings 和 CreateGlobalFunctionBindings 具体方法绑定的名称列表。

表 18 - 全球环境记录的附加字段

[[ObjectRecord]]: Object Environment Record

绑定对象是全局对象。它包含全局内置绑定以及关联 Realm 的全局代码中的 FunctionDeclaration、GeneratorDeclaration 和 VariableDeclaration 绑定。 p> [[DeclarativeRecord]]: Declarative Environment Record

包含关联领域代码的全局代码中所有声明的绑定,FunctionDeclaration、GeneratorDeclaration 和 VariableDeclaration 绑定除外。

[[VarNames]]: List 的字符串

在关联Realm的全局代码中,由FunctionDeclaration、GeneratorDeclaration和VariableDeclaration声明绑定的字符串名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    相关资源
    最近更新 更多