【问题标题】:JavaScript, separate instance of the same function return different value for the same closed variableJavaScript,同一函数的单独实例为同一封闭变量返回不同的值
【发布时间】: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


【解决方案1】:

每次调用 test2 时,引擎都会创建一个新的闭包。

如果你想重复使用同一个闭包,那么你也必须使用同一个变量:

function test2() {
  var a = Date.now();
  return function() {console.log(a)}
}

var b = test2();
b();
b(); // the same

【讨论】:

  • 那么我将其概念化为以下内容是否正确:范围就像类定义而闭包就像范围的实例化?
  • 我不建议你这样想。不要考虑类和对象,因为那是另一个抽象层次。假设每个闭包都保持其范围(它有自己的局部变量)并且在您直接在闭包中访问之前它们不会发生变异
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多