Feel free to skip straight to TL/DR if you're not interested in details of the question
简短的序言:
我最近决定从头开始完全重新学习 JavaScript。 这次不仅是它如何工作,还有它为什么工作。一旦您还了解了编译器的工作原理和所有其他细节,一切都会变得更有意义,问题是这个小的预构建表达式:
而且我无法完全理解它为什么有效,当它似乎违反 JS 现有的所有词法和范围规则时。
我没有得到的东西:
它不应该打破范围吗?
这里我们只使用 2 个级别的范围。
try{ }
内的范围 catch{ }
内的范围和 global
范围。如果我们要说明这一点,它看起来像这样:
现在这两个内部作用域应该充当两个独立的作用域并且不会相互冲突。考虑到这一点,**为什么 try {}
的值返回到 catch {}
block ,而它应该作为范围包含在自身中。
我什至尝试使用 "use strict";
来查看我是否能以某种方式捕获试图在 block 范围之外传递参数的异常,但即便如此...... nada,仍按预期工作:
Technically I created an extra scope here with the
function()
, unfortunately it's impossible to use strict mode in jsfiddle without self-invoked function
(function(){
"use strict";
try {
throw 'MadeUpError';
}
catch(e) {
console.log(e);
}
})();
为什么 try {}
block 能够将参数传递给 catch {}
block ,尽管它与 冲突>严格模式
?
当标识符 (e)
应该只在它自己的范围内是唯一的时,这似乎很不合逻辑。
此外,我什至无法从词汇上理解它。
catch block 要求对抛出的异常的不存在的索引 (?) 进行右侧查找。
它从哪里以及如何知道应该从哪里检索异常?
长话短说:
可能回答这个问题最简单的方法是用编译器的伪语言来回答它:例如。
/*
1. I arrived at try { } block
2. Created a new Exception
3. I stored Exception at (?)
4. Exited try { }
5. I looked up Exception from ...
*/
希望你能收到我冗长的帖子。我知道这更像是一个理论问题,但我想完全理解try..catch
操作期间幕后发生的事情。
最佳答案
我到达
try {
block 并将其位置压入try {
block 的堆栈(当}
已达到)*我执行 block 内的代码
我到达了一个
throw whatever
我将
whatever
评估为一个表达式(如果它是一个标识符,我会在当前范围内查找它)我将评估结果存储在一个临时内部变量中
我从堆栈中查找最上面的
try { }
并将其弹出我转到相关的
catch(identifier) { }
block我在 catch block 的范围内创建了
identifier
,并将内部变量的值复制到它我执行 catch block
我在 catch block 之后执行代码
(这非常简单,它甚至在 async
函数内部变得有点复杂),您可以在 ECMA 规范的 $13.15.7/8 处阅读整个故事。
Shouldn't it break the scope?
抛出的东西根本不必是 try { }
范围的一部分:
throw new Error();
也可以只是表达式的一部分。但是,如果它是范围的一部分:
const error = new Error();
throw error; // <- handed over to some internal engine logic
然后抛出它会导致它被复制出作用域(进入某个内部变量),作用域将停止存在(因为 block 停止执行)并且它将被复制到新作用域的新变量中:
catch(err) { // <- the error suddenly appears from inside the engine here
因此会有两个作用域和两个变量,但它们具有相同的值。
*规范将其定义为 block 的递归评估,然后将在 throw
语句处结束,直到到达 Try block ,但我认为使用堆栈更容易理解(它递归将在最后)。
关于javascript - 在 try catch 操作期间*究竟*发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51408832/