在 JavaScript 的上下文中说 "assign a closure to a variable" 是正确的吗?
Is saying to "assign a closure to a variable" correct in the context of JavaScript?
我很好奇我的示例代码中第 20 行的解释。
On line 9 variable with name func1
is declared. It's assigned to
the closure that is returned by the function foo()
invocation.`
我知道调用函数 foo()
returns 函数 bar
和指向变量 a
的指针都在其词法范围内。由于闭包是 a function combined with all of the variables in its lexical scope, including function and class names
,我可以说我正在将变量 func1
分配给闭包吗?
这个解释是否用词正确,不含糊?您能否建议更好、更简洁的解释和释义第 20 行?
function foo() {
let a = 1;
return function bar() {
a += 100;
console.log(a);
}
}
let func1 = foo();
let func2 = foo();
func1(); // ???
func2(); // ???
func1(); // ???
func2(); // ???
/*
On line 9 variable with name `func1` is declared.
!! It's assigned to the closure that is returned by the function `foo()` invocation.
The closure contains a pointer to the variable `a` that is in the lexical scope of the function `bar` that is returned by the `foo` invocation.
On line 10 variable with name `func2` is declared. It's assigned to the value of closure that is returned by the function `bar()` invocation. The closure contains a pointer to the variable `a` that is in the lexical scope of the function `bar`.
Variables accessible through the closure during the `func1` invocation and `func2` invocation are two separate independent variables that just happen to have the same name (`a`).
That is, this program would print the following to the console:
- 101
- 101
- 201
- 201
*/
I know that the invocation of the function foo()
returns both the function bar
and the pointer to the variable a
which is in its lexical scope.
它只是 returns 一件事:foo
创建的函数 bar
。函数 bar
本身引用了创建它的环境,因此引用了 a
变量;它 关闭 那个环境。所以 bar
是一个闭包。您在 JavaScript 代码中创建的所有函数都是闭包。
...can I say that I am assigning the variable func1 to the closure?
你不能给闭包赋值;恰恰相反。您可以分配给(各种类型的)变量,也可以初始化常量。您在 const func1 = foo();
中所做的是使用 foo
.
返回的函数(如果您愿意,可以说“闭包”)初始化常量 func1
I know that the invocation of the function foo() returns both the
function bar and the pointer to the variable a
闭包不是这样工作的。 foo()
仅调用 returns 函数 bar
,它不会 returns 指向变量 a
.
的指针
每个环境都link到它的外部环境,当javascript在当前环境中找不到变量时,它会跟随link到外部环境。 link不同环境之间的年龄是闭包的原因。
定义函数 foo
时,javascript 将 link 保存到函数的全局环境中,规范调用函数的 [[Environment]]
槽.
调用函数 foo
时,会为该调用创建一个新环境,并将其 link 编辑到保存在函数 [[Environment]]
插槽中的环境中foo
(我们称此环境为 EnvFoo
。)
同样,当bar
函数被定义时,javascript保存link函数foo
时创建的环境(EnvFoo
)在 bar
函数的 [[Environment]]
槽中调用。当 bar
被调用时,一个新的环境被创建(我们称这个环境为 EnvBar
)并且它得到一个 link 到保存在 [=11=14=] 插槽中的环境=]函数(EnvFoo
),作为其外部环境。
所以当你调用bar
函数时,变量a
在当前环境(EnvBar
)中不存在,所以javascript寻找变量a
在当前环境的外部环境中,即EnvFoo
。这个环境包含变量a
,所以它从这个外部环境中得到a
的值,即EnvFoo
.
这就是闭包的工作方式,即每个环境都保留对其外部环境的引用,当 javascript 在当前环境中找不到变量时,它会跟随 link 到当前环境环境的外部环境并在那里寻找变量。它继续跟随 link 到外部环境,直到它到达全球环境。
下图将让您了解每种环境在您的案例中是如何link的。
P.S: 我上面解释的是我从@T.J Crowder's book中学到的东西。如果你想深入了解,我建议你参考这本书,因为书中有详细的解释。
我很好奇我的示例代码中第 20 行的解释。
On line 9 variable with name
func1
is declared. It's assigned to the closure that is returned by the functionfoo()
invocation.`
我知道调用函数 foo()
returns 函数 bar
和指向变量 a
的指针都在其词法范围内。由于闭包是 a function combined with all of the variables in its lexical scope, including function and class names
,我可以说我正在将变量 func1
分配给闭包吗?
这个解释是否用词正确,不含糊?您能否建议更好、更简洁的解释和释义第 20 行?
function foo() {
let a = 1;
return function bar() {
a += 100;
console.log(a);
}
}
let func1 = foo();
let func2 = foo();
func1(); // ???
func2(); // ???
func1(); // ???
func2(); // ???
/*
On line 9 variable with name `func1` is declared.
!! It's assigned to the closure that is returned by the function `foo()` invocation.
The closure contains a pointer to the variable `a` that is in the lexical scope of the function `bar` that is returned by the `foo` invocation.
On line 10 variable with name `func2` is declared. It's assigned to the value of closure that is returned by the function `bar()` invocation. The closure contains a pointer to the variable `a` that is in the lexical scope of the function `bar`.
Variables accessible through the closure during the `func1` invocation and `func2` invocation are two separate independent variables that just happen to have the same name (`a`).
That is, this program would print the following to the console:
- 101
- 101
- 201
- 201
*/
I know that the invocation of the function
foo()
returns both the functionbar
and the pointer to the variablea
which is in its lexical scope.
它只是 returns 一件事:foo
创建的函数 bar
。函数 bar
本身引用了创建它的环境,因此引用了 a
变量;它 关闭 那个环境。所以 bar
是一个闭包。您在 JavaScript 代码中创建的所有函数都是闭包。
...can I say that I am assigning the variable func1 to the closure?
你不能给闭包赋值;恰恰相反。您可以分配给(各种类型的)变量,也可以初始化常量。您在 const func1 = foo();
中所做的是使用 foo
.
func1
I know that the invocation of the function foo() returns both the function bar and the pointer to the variable a
闭包不是这样工作的。 foo()
仅调用 returns 函数 bar
,它不会 returns 指向变量 a
.
每个环境都link到它的外部环境,当javascript在当前环境中找不到变量时,它会跟随link到外部环境。 link不同环境之间的年龄是闭包的原因。
定义函数 foo
时,javascript 将 link 保存到函数的全局环境中,规范调用函数的 [[Environment]]
槽.
调用函数 foo
时,会为该调用创建一个新环境,并将其 link 编辑到保存在函数 [[Environment]]
插槽中的环境中foo
(我们称此环境为 EnvFoo
。)
同样,当bar
函数被定义时,javascript保存link函数foo
时创建的环境(EnvFoo
)在 bar
函数的 [[Environment]]
槽中调用。当 bar
被调用时,一个新的环境被创建(我们称这个环境为 EnvBar
)并且它得到一个 link 到保存在 [=11=14=] 插槽中的环境=]函数(EnvFoo
),作为其外部环境。
所以当你调用bar
函数时,变量a
在当前环境(EnvBar
)中不存在,所以javascript寻找变量a
在当前环境的外部环境中,即EnvFoo
。这个环境包含变量a
,所以它从这个外部环境中得到a
的值,即EnvFoo
.
这就是闭包的工作方式,即每个环境都保留对其外部环境的引用,当 javascript 在当前环境中找不到变量时,它会跟随 link 到当前环境环境的外部环境并在那里寻找变量。它继续跟随 link 到外部环境,直到它到达全球环境。
下图将让您了解每种环境在您的案例中是如何link的。
P.S: 我上面解释的是我从@T.J Crowder's book中学到的东西。如果你想深入了解,我建议你参考这本书,因为书中有详细的解释。