函数声明和函数表达式在调试时差异显著:函数声明的name属性准确稳定,调用栈和断点均显示函数名;匿名函数表达式堆栈显示为anonymous,命名函数表达式可提升可读性;var函数表达式存在暂时性死区,报错信息可辅助判断定义方式。

函数声明和函数表达式在调试时表现明显不同,核心在于 name 属性、调用栈显示、断点定位精度 这三点。
函数名在 DevTools 中是否可见
函数声明的 name 属性始终准确、稳定:
-
function greet() {}→greet.name返回"greet" - 无论在哪调用,Chrome/Firefox 的 Sources 面板里都能直接看到函数名,断点也标记为
greet
函数表达式是否具名决定堆栈可读性
匿名函数表达式(如 const fn = function() {})在调用栈中显示为 anonymous 或空字符串;而命名函数表达式(NFE)能显著改善调试体验:
const factorial = function fact(n) { return n-
factorial.name是"fact",但外部无法访问fact - 报错或断点触发时,堆栈显示
fact而非anonymous,递归调用路径一目了然
箭头函数与方法简写无 name 属性
箭头函数、对象方法简写(obj = { method() {} })、类中方法都不具备独立 name 属性:
-
const add = (a, b) => a + b;→add.name是空字符串"" - 它们在 DevTools 中常显示为
add(靠变量名推断),但一旦脱离上下文(如传入回调),就退化为anonymous - 调试异步链或高阶函数时,这类函数容易在堆栈中“消失”,增加排查难度
控制台输出和错误提示的语义差异
运行时报错信息本身就能反推定义方式:
-
ReferenceError: xxx is not defined→ 变量名根本没进作用域(大概率是 let/const 函数表达式未执行到声明行) -
TypeError: xxx is not a function且console.log(xxx)输出undefined→ 是 var 函数表达式,已声明但未赋值 - 能正常调用且
xxx.toString()显示function xxx() { ... }→ 基本确认是函数声明











