【发布时间】:2019-07-28 00:58:47
【问题描述】:
您好,我正在阅读系列丛书"You Don't Know JS"。我正在第二次尝试更深入地了解内容。在阅读有关范围和闭包的章节时。我想到了以下场景:
考虑这个例子
function test1(){
var a = 2;
return function(){console.log(a)};
}
var b = test1();
b(); // 2
var c = test1();
c(); // 2
“test()”返回的函数在“test”范围内保持一个闭包。所以每次我们调用这个返回的函数时,我们都会得到变量“a”的值,在这种情况下是“2”。现在考虑这个例子:
function test2() {
var a = Date.now();
return function() {console.log(a)}
}
var b = test2();
b(); // 1551867093995
var c = test2();
c(); // 1551867109249
每次我们执行“test()”时,变量“a”在函数“test()”被调用时被赋值,并返回一个在“test()”范围内保持闭包的函数。
我们在两个单独的实例上调用“test()”,将返回的函数分配给变量“b”和“c”。
请注意,当我们调用“b()”和“c()”时,我们会得到 2 个不同的值,即使每次调用都引用相同范围内的相同变量 (var a)。
似乎每次我们调用一个函数(例如“test2()”)时,引擎都会为该函数的每次调用创建一个声明函数作用域的唯一实例,并且无论存在什么闭包,都会在一个唯一的实例上关闭功能范围。就好像每个函数声明都创建了一个“作用域类”来描述它自己的作用域,并且每次调用该函数时都会创建一个“作用域类”的实例。真的是这样吗?有人能解释一下这种行为,或者给我指出更深入地解释 JavaScript 作用域的资源吗?
谢谢
【问题讨论】:
-
"每次我们调用一个函数时,引擎都会为该函数的每次调用创建一个声明函数作用域的唯一实例" 是的,这是正确的。这几乎就是它的全部内容 - 每个函数调用都会创建一个新范围。 “闭包”实际上只是一个函数范围,您可以在调用内部未命名函数时传递和访问它。
-
谢谢@VLAZ。您知道有什么资源可以解释 JS 引擎如何创建作用域的内部原理吗?我正在寻找对“You Don't Know JS”一书提供的更深入的了解。
标签: javascript function scope closures internals