想象你有个背包(函数),每次出门时都会把当时看到的
风景(外部变量)装进去。
闭包就是这个背包——即使离开了那个地方,你依然能拿出当时装的风景
函数声明方式
function greet(name) {
return "Hello " + name
}
const greet = function(name) {
return "Hello " + name
}
const greet = (name) => {
return "Hello " + name
}
const greet = name => "Hello " + name
试试调用函数
{{ functionResult }}
点击"调用"按钮看结果...
function createCounter() {
let count = 0
return function() {
count++
return count
}
}
const counter = createCounter()
闭包环境
count =
{{ counterValue }}
发生了什么?
createCounter() 执行后,局部变量 count 本该消失
- 但返回的函数"记住"了这个变量(形成了闭包)
- 每次调用
counter() 都在访问同一个 count
- 外部无法直接访问
count(实现了数据私有化)
function makeMultiplier(times) {
return function(n) {
return n * times
}
}
const double = makeMultiplier(2)
const triple = makeMultiplier(3)
double = makeMultiplier(2)
闭包捕获 times = 2
triple = makeMultiplier(3)
闭包捕获 times = 3
{{ multiplyResult }}
🔍 变量查找过程(作用域链)
查找规则:
从当前作用域开始,逐层向外查找,直到全局作用域。找不到则报错 ReferenceError。
💡
核心思想:
函数是 JavaScript 中的一等公民,可以赋值给变量、作为参数传递、作为返回值。箭头函数更简洁,且不绑定自己的 this。
闭包是函数和声明该函数的词法环境的组合。它让函数可以访问外部作用域的变量,即使外部函数已经执行完毕。闭包常用于数据私有化、函数工厂、模块化等场景。
作用域链是 JavaScript 查找变量的机制。当访问一个变量时,引擎会先在当前作用域查找,找不到就去外层作用域找,直到全局作用域。这种机制让内层函数可以访问外层变量,形成了闭包的基础。