函数表达式定义闭包需满足三条件:外部函数内定义内部函数、内部函数引用外部局部变量、外部函数返回内部函数对象(不调用);如make_adder中lambda引用x并return add,形成记住x=10的闭包。

函数表达式定义闭包,核心在于:用变量保存一个内部函数,该函数引用了外部函数的变量,并且外部函数返回这个内部函数(不加括号调用),从而形成闭包。它和函数声明方式的关键区别在于执行时机与作用域绑定方式。
闭包必须满足的三个条件
用函数表达式实现闭包时,需同时满足:
- 外部函数中定义内部函数(嵌套)
- 内部函数引用外部函数的局部变量(非全局,也非参数传入的副本,而是“捕获”的原始绑定)
- 外部函数返回内部函数对象(不是调用结果,即不写 inner(),而写 inner)
典型函数表达式闭包写法
下面是一个清晰、可运行的 Python 示例:
def make_adder(x):
# 内部函数用函数表达式定义(匿名或具名均可)
add = lambda y: x + y # 引用了外部变量 x
return add # 返回函数对象,不是调用结果
使用方式:
f = make_adder(10)
print(f(3)) # 输出 13
print(f(5)) # 输出 15
这里 f 就是闭包:它记住了 x = 10 这个环境,每次调用都基于该固定值运算。
为什么必须用函数表达式?和声明式有何不同?
函数表达式(如 lambda 或 def inner():... 赋值给变量)让内部函数成为可传递、可返回的一等公民;而函数声明(def inner():)在作用域内虽也能形成闭包,但表达式写法更凸显“返回函数对象”这一动作,逻辑更显性。
常见误区:
- 写成 return add() → 返回的是数值,不是闭包
- 在外部直接调用 add(2) → add 作用域仅限于 make_adder 内部,外部不可见
- 把 x 改成全局变量 → 不再是“自由变量”,不构成严格意义的闭包
JavaScript 中的函数表达式闭包实例
对比理解更直观:
function createCounter(init) {
let count = init;
return function() { // 函数表达式形式的内部函数
count++;
return count;
};
}
const counter = createCounter(10);
console.log(counter()); // 11
console.log(counter()); // 12
这里的 function() {...} 是匿名函数表达式,被返回后持续访问并修改外部的 count,正是闭包行为。

















