JavaScript 中的“闭包”是什么?
什么是“闭包”?
闭包是函数与其周围状态(词法环境)的引用的组合。它允许你从内部函数访问外部函数的作用域或环境。
考虑以下代码片段:
function outerFunction() {
let innerVar = "I'm inside outerFunction";
function innerFunction() {
console.log(`${innerVar}, but I can be accessed from innerFunction too!`);
}
innerFunction();
}
outerFunction();
// > "I'm inside outerFunction, but I can be accessed from innerFunction too!"
词汇范围/环境
在上面的代码片段中,outerFunction
创建了一个名为 的变量innerVar
和一个名为 的函数innerFunction
。innerFunction
函数被包含在 内部,并且仅在 内部可用outerFunction
。innerFunction
它本身没有局部变量,但 能够访问,innerVar
因为它们都在的词法作用outerFunction
域内。
关闭
在最初的代码片段中,我们innerFunction
在声明后立即调用了它。但是如果我们return
改为使用内部函数呢?
function outside() {
let myName = 'Pixi';
function inside() {
alert(myName);
}
return inside;
}
let insideOutside = outside();
insideOutside();
如果我们运行这段代码,就会收到一条包含我名字的警报。但是为什么呢?
之所以有效,是因为 JavaScript 中的函数构成了闭包。闭包是函数和声明该函数的词法作用域的组合。
insideOutside
inside
在运行时, 成为对我们函数实例的引用outside
。这个 的实例维护着对其词法作用域inside
的引用,这使得它能够维护对变量的引用。myName
传递参数
我们可以利用闭包来创建接受参数的封闭函数。
/* we create a function that accepts one argument,
and returns a function that also accepts one argument,
and utilizes both arguments... */
function makeMultiplier(x) {
return function (y) {
return x * y;
};
}
/* we can call the outer function
and assign it to a variable */
let multiplyBy2 = makeMultiplier(2);
let multiplyBy5 = makeMultiplier(5);
console.log(multiplyBy2(3)); // 6
console.log(multiplyBy5(3)); // 15
/* we can also use argument chaining to call
both functions at once */
console.log(makeMultiplier(2)(3)); // 6
console.log(makeMultiplier(5)(3)); // 15
我们的新makeMultiplier
功能使我们能够创建更多功能,然后在以后使用这些功能。
当我们创建 时multiplyBy2
,对 的引用将成为函数词法作用域x = 2
的一部分。然后我们可以使用此函数将其他数字乘以 2。对于 也是如此。multiplyBy5
当我们使用参数链时,我们只需通过传递一个参数来立即调用内部函数makeMultiplier
,并立即将一个参数传递给它返回的函数。
想要了解有关 JavaScript 中范围的更多信息吗?
看看我之前关于作用域和变量提升的文章,如果还有任何疑问,请告诉我!说不定以后还能写出一篇新的博文!
xx - 艾米丽 / TheCodePixi
外部资源: |
---|
MDN 关闭文档 |