84669 人学习
152542 人学习
20005 人学习
5487 人学习
7821 人学习
359900 人学习
3350 人学习
180660 人学习
48569 人学习
18603 人学习
40936 人学习
1549 人学习
1183 人学习
32909 人学习
如何向一个对JavaScript闭包的概念(例如函数、变量等)有了解,但不理解闭包本身的人解释闭包?
我看过维基百科上给出的Scheme示例,但不幸的是没有帮助。
在JavaScript中,每个函数都维护着与其外部词法环境的链接。词法环境是一个作用域内所有名称(例如变量、参数)及其值的映射。
所以,每当你看到function关键字时,该函数内部的代码可以访问在函数外部声明的变量。
function
function foo(x) { var tmp = 3; function bar(y) { console.log(x + y + (++tmp)); // 将输出 16 } bar(10); } foo(2);
这将输出16,因为函数bar闭包了参数x和变量tmp,它们都存在于外部函数foo的词法环境中。
16
bar
x
tmp
foo
函数bar与其与函数foo的词法环境的链接一起,构成了一个闭包。
函数不需要返回来创建一个闭包。仅通过声明,每个函数都会闭包其封闭的词法环境,形成一个闭包。
function foo(x) { var tmp = 3; return function (y) { console.log(x + y + (++tmp)); // 也将输出 16 } } var bar = foo(2); bar(10); // 16 bar(10); // 17
上述函数也将输出 16,因为bar中的代码仍然可以引用参数x和变量tmp,尽管它们不再直接在作用域内。
然而,由于tmp仍然存在于bar的闭包中,它可以被递增。每次调用bar时,它都会递增。
闭包的最简单示例是:
var a = 10; function test() { console.log(a); // 将输出 10 console.log(b); // 将输出 6 } var b = 6; test();
当JavaScript函数被调用时,会创建一个新的执行上下文ec。除了函数参数和目标对象之外,该执行上下文还接收到调用执行上下文的词法环境的链接,这意味着在外部词法环境中声明的变量(在上面的示例中,即a和b)可以从ec中访问。
ec
a
b
每个函数都创建了一个闭包,因为每个函数都有与其外部词法环境的链接。
请注意,闭包中可见的是变量本身,而不是副本。
闭包是以下内容的配对:
词法环境是每个执行上下文(堆栈帧)的一部分,它是标识符(即局部变量名)和值之间的映射。
JavaScript中的每个函数都保持对其外部词法环境的引用。当函数被调用时,此引用用于配置创建的执行上下文。此引用使函数内部的代码能够“看到”在函数外部声明的变量,无论函数何时何地被调用。
如果一个函数是由另一个函数调用的,那么就会创建一系列对外部词法环境的引用。这个链条被称为作用域链。
在下面的代码中,inner与调用foo时创建的执行上下文的词法环境形成了闭包,闭包包含变量secret:
inner
secret
function foo() { const secret = Math.trunc(Math.random() * 100) return function inner() { console.log(`The secret number is ${secret}.`) } } const f = foo() // 无法直接从外部访问`secret` f() // 检索`secret`的唯一方法是调用`f`
在JavaScript中,每个函数都维护着与其外部词法环境的链接。词法环境是一个作用域内所有名称(例如变量、参数)及其值的映射。
所以,每当你看到
function
关键字时,该函数内部的代码可以访问在函数外部声明的变量。这将输出
16
,因为函数bar
闭包了参数x
和变量tmp
,它们都存在于外部函数foo
的词法环境中。函数
bar
与其与函数foo
的词法环境的链接一起,构成了一个闭包。函数不需要返回来创建一个闭包。仅通过声明,每个函数都会闭包其封闭的词法环境,形成一个闭包。
上述函数也将输出 16,因为
bar
中的代码仍然可以引用参数x
和变量tmp
,尽管它们不再直接在作用域内。然而,由于
tmp
仍然存在于bar
的闭包中,它可以被递增。每次调用bar
时,它都会递增。闭包的最简单示例是:
当JavaScript函数被调用时,会创建一个新的执行上下文
ec
。除了函数参数和目标对象之外,该执行上下文还接收到调用执行上下文的词法环境的链接,这意味着在外部词法环境中声明的变量(在上面的示例中,即a
和b
)可以从ec
中访问。每个函数都创建了一个闭包,因为每个函数都有与其外部词法环境的链接。
请注意,闭包中可见的是变量本身,而不是副本。
闭包是以下内容的配对:
词法环境是每个执行上下文(堆栈帧)的一部分,它是标识符(即局部变量名)和值之间的映射。
JavaScript中的每个函数都保持对其外部词法环境的引用。当函数被调用时,此引用用于配置创建的执行上下文。此引用使函数内部的代码能够“看到”在函数外部声明的变量,无论函数何时何地被调用。
如果一个函数是由另一个函数调用的,那么就会创建一系列对外部词法环境的引用。这个链条被称为作用域链。
在下面的代码中,
inner
与调用foo
时创建的执行上下文的词法环境形成了闭包,闭包包含变量secret
: