- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在ECMAScript specification内,我们在哪里可以找到关于为什么 let
和 const
无法在使用 BlockStatements 创建的词法环境之外访问的明确规范>(与使用 var
声明的变量相反)?
如果BlockStatements现在创建new lexical environments ,那么 let
和 const
声明不应创建在该词法环境之外可访问的变量,但 var
变量应该创建。我试图了解最新的 ECMAScript 规范中具体指定了该行为的位置。
来自 13.3.1 Let and Const Declarations :
let and const declarations define variables that are scoped to the running execution context's LexicalEnvironment. The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable's LexicalBinding is evaluated.
来自 13.3.2 Variable Statement :
A var statement declares variables that are scoped to the running execution context's VariableEnvironment. Var variables are created when their containing Lexical Environment is instantiated and are initialized to undefined when created.
正如所见,两个变量声明在实例化它们所包含的词法环境时都会创建变量。对于 BlockStatement 来说,就是编译器进入 block 的时间。
LexicalEnvironment and VariableEnvironment components of an execution context are always Lexical Environments
最佳答案
正如您在 var
的描述中看到的,它的作用域为正在运行的执行上下文的 VariableEnvironment
。有一个顶级 VariableEnvironment
,然后创建一个新的 when you enter a function然后在 this part about Execution Contexts ,它是这样说的:
The LexicalEnvironment and VariableEnvironment components of an execution context are always Lexical Environments. When an execution context is created its LexicalEnvironment and VariableEnvironment components initially have the same value.
因此,在函数开始时,词法环境和变量环境是相同的。
然后,进入13.2.13 Runtime Semantics: Evaluation Block: { } ,您可以看到,当您进入该 block 时,会创建一个新的 LexicalEnvironment
,而当您离开该 block 时,会恢复之前的环境。但是,当您进入或离开 block 时,没有提及新的 VariableEnvironment
(因为它在函数内保持不变)。
因此,由于 let
和 const
的作用域是声明它们的 LexicalEnvironment,并且是 block 本地的,因此无法在 block 外部访问它们。
但是,var
的作用域为 VariableEnvironment
,它仅被创建并限定为整个函数,而不是一个 block 。
let
和 const
变量无法在其 LexicalEnvironment 之外访问,因为一旦执行上下文离开其 block (一旦当您离开该 block 时,它们的 LexicalEnvironment 本质上会从堆栈中弹出,并且不再位于解释器查找变量的作用域搜索链中。
当规范添加此内容时:
The [
let
andconst
] variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable's LexicalBinding is evaluated.
这意味着即使在它们自己的词法环境中,您也无法访问它们,直到评估它们的定义为止。通俗地说,这意味着它们不会像 var
那样被提升到其作用域的顶部,因此在定义之后才能使用。这是通过在 LexicalEnvironment
中不初始化 let
或 const
变量来实现的,直到它的语句运行并且 GetBindingValue()
查找变量的操作会发现它尚未初始化,并会抛出ReferenceError
。 var
变量立即初始化为 undefined
,因此它们不会导致此 ReferenceError
。
您可以在这段代码中看到它是如何工作的:
let x = 3;
function test() {
x = 1;
let x = 2;
console.log("hello");
}
test();
在 let x = 3
行,变量 x
在外部 LexicalEnvironment 中初始化。
然后,当您调用 test()
时,在该函数的开头,会创建一个新的 LexicalEnvironment,该 block 中 x
的新声明将被放入新的 LexicalEnvironment
,但尚未初始化。
然后,您将看到 x = 1
语句。解释器查找x
,在当前LexicalEnvironment
中找到它,但它尚未初始化,因此抛出ReferenceError
。
根据您评论中的问题:
I've been turning the spec upside down, but have a hard time spotting that VariableEnvironments are only created for functions. Could you perhaps add an answer showing what steps in the spec you follow to reach said conclusion?
您只需浏览规范中创建 VariableEnvironment
的所有位置,您就会发现这种情况发生的唯一位置是函数执行的开始处和顶层。
例如,以下是这些地方的一个:PrepareForOrdinaryCall 。还有其他一些。
但是,没有任何地方描述过在 block 开始时发生的这种情况,而只是在函数开始时描述。
这些规范的编写方式,它们描述了事情发生的时间,而不是没有发生的时间(这具有一定的逻辑意义),但这意味着要证明某事没有发生,你必须在任何地方都找不到这说明它确实发生了。
关于javascript - ECMAScript : Where can we find specification about accessibility of let/const variables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51543843/
我正在尝试编写 Access Access 数据库的脚本,以便在命令行上使用。 Access 数据库使用工作组文件进行保护。 Dim oApp, sWGF,myWS Set sApp = Create
我有一个包含数据表的表格。我希望用户能够选择多行,单击按钮并运行一些 sql 查询并对这些行执行一些工作。 查看我的 VBA 代码,我发现如何使用 CurrentRecord 属性 Access 最后
如果我在某个网络位置有 Microsoft Access 2007 数据库,那么可以使用该数据库的客户端计算机的数量是否有限制?客户端不会安装 Access,而是使用 Access Runtime 2
我正在开发一个注册系统。但我收到此错误:You tried to execute a query that does not include the specified expression.. 我正
我有一个产品设计为使用 MS Access 文件作为数据库的桌面产品。 现在,一些用户需要将它安装在几台 PC(比如说 2 或 3 台)上并共享数据库。 我想将 MS Access 文件放在共享文件夹
我接手了一个旧的软件项目,该项目使用 MS Access 数据库来存储数据。但是数据库不会在 Access 中打开,如下所示: "You do not have the necessary permi
我有一个文件夹,里面装满了 100 多个 Access97 文件。我需要将它们全部更新到 Access2003。 我可以手动完成,但使用 VBA 可能会快很多。 有没有人会有一个片段可以做到这一点?或
我正在通过 SQL Server 迁移助手 (SSMA) 将数据从 Access 数据库迁移到 SQL Server。 Access 应用程序将继续与转换为链接表的本地表一起使用。 一个连续的表单在加
我正在通过 SQL Server 迁移助手 (SSMA) 将数据从 Access 数据库迁移到 SQL Server。 Access 应用程序将继续与转换为链接表的本地表一起使用。 一个连续的表单在加
我的公司用 Visual Basic 6 开发了一个应用程序。 该应用程序通过 ODBC 数据源使用 Access 数据库。 Access 数据库是一个扩展名为“.mdb”的文件。 在以下环境中运行应
我一直在尝试让 Microsoft Access 从主 Access 窗口中“退出”,以便我可以隐藏 Access 窗口并仅在桌面上显示表单,以便可以轻松地将其放置在其他应用程序旁边。 起初我发现了一
我想在 access 2010 中使用 access 2000 和 2003 数据库。由于我不想检查一切是否手动工作,我正在寻找一种工具来分析 VBA 代码以查找使用 access 2010 发生的错
所以我有一个 Excel 工作簿,其中有一个很好的 shaperange 对象的全局 map 。通过一些非常简单的代码,我可以更改颜色、将国家/地区集合分组和取消分组为数组等......并且效果非常好
我们希望有大约 35-40 人通过共享驱动器上的脚本写入 Access 数据库。这些指标分解为他们需要每小时写大约 3-7 次。 Access 会支持这一点而不会对我产生影响吗? 是的,我很乐意将其用
我正在寻找一种使用 VBA 代码从外部数据库文件中删除 VBA 模块的方法。名为“myfile.accdb”的外部文件有一个名为“mod1”的模块,我希望能够在单独的项目中使用 VBA 代码删除该模块
我在 Access 2003 数据库(在 Access 2007 中开发)中有三个表单,它们处于父级 -> 子级 -> 孙子级关系中。在子窗体的 'Form_Load' 子窗体中,我设置了孙子窗体的一
MS Access 2007 存在拒绝在设计模式下显示表单的问题。我可以看到表单的代码(如果我查看显示表单的按钮的事件属性),但我看不到作为 GUI 布局的表单。而且,当我尝试从应用程序的主窗口调用此
我编写了代码,使用 Excel 中的下拉列表提供的标准将两个表连接起来,然后将数据返回到电子表格上的特定位置(工作表上已经有标题)。 这在我的机器上和其他机器上使用 MS Access 的机器上都可以
我正在开始构建一个应用程序,该应用程序从给定的根路径开始遍历文件夹结构,并将所有找到的 Access 1997 .mdb 文件转换为较新的 Access 2007/2010 .accdb 格式。但是,
我有一个表单和一个按钮。我想通过单击按钮打开另一个表单,并将参数从父表单传递到子表单(子表单的 RecordSource 有参数)。我该怎么做? 最佳答案 您可以通过引用表单的对象来引用调用表单的任何
我是一名优秀的程序员,十分优秀!