函数字面量在赋值语句中是否为表达式?为何使用function expression术语?
背景
表达式描述计算过程并会求值为一个值。
> a=2 // 2 is an expression in assignment statement > 3 // is an expression > [1,2] // is an expression > {'a':2, 'b':[1,2,3]} // is an expression > mul(add(4, mul(4, 6)), add(3, 5)) // is an expression > let result = sum(1,2) // sum(1,2) is an expression in this assignment statement, only because it returns value 3 > console.log(materials.map(material => material.length)); // material => material.length is a sub-expression > console.log(materials.map(material => console.log('abc'))); // material => console.log('abc') is not an expression > Math.random() // random() is a method expression > console.log('xyz') // log('xyz') is a method expression > new Date(2012, 11) // is an expression
在上述示例中,sum(1,2)、material => material.length 以及 mul(add(4 , mul(4, 6)), add(3, 5)) 属于调用表达式(call expressions),因为它们遵循以下求值规则:
call expressions的求值流程:
- 先计算操作符子表达式,再计算操作数子表达式
- 将操作符子表达式求值得到的函数应用于操作数子表达式求值得到的参数
而material => console.log('abc')不遵循该求值规则——因为它的执行结果是undefined,本质是执行一个无返回值的操作,不符合表达式「求值为一个可用值」的核心特征。
有观点指出,不对表达式和命令做严格区分,能实现引用透明性(即表达式可以被它的求值结果替换,且不影响整个程序的行为)和自底向上解析(从最基础的表达式开始组合成更复杂的代码结构),让语言的概念体系更一致。
问题解答
直接给结论:你提到的函数字面量 function(){ console.log('output') } 在语句 let f = function(){ console.log('output') } 里完全属于表达式。
至于为什么要用「函数表达式(function expression)」这个术语,得从JavaScript中函数的两种核心存在形式说起:
- 一种是函数声明,比如
function f() { console.log('output') },它是独立的语句,作用是在当前作用域声明一个函数变量,会被语法提升,且常规场景下必须带有函数名。 - 另一种就是函数表达式,它是把函数定义当作一个「值」来使用——就像你例子里那样,把它赋值给变量
f,这时候它本质上是一个能求值为函数对象的表达式,和2、[1,2]这类表达式没有本质区别,都是「能产生一个可用值」的计算过程。
简单来说,这个术语是为了明确区分「作为语句存在的函数声明」和「作为值存在的函数表达式」——二者在语法规则(比如提升特性)、使用场景上都有明显差异,用不同术语能更清晰地描述它们的定位。
内容的提问来源于stack exchange,提问作者overexchange
相关产品推荐
相关产品推荐

