JavaScript函数定义有三种:函数声明(提升)、函数表达式(不提升)、箭头函数(不绑定this);参数均为值传递,原始类型传副本,对象类型传地址副本;推荐用剩余参数...args处理不定参;默认参数和解构默认值需注意暂时性死区与null陷阱。

JavaScript 函数定义有哪几种写法?
最常用的是函数声明和函数表达式,箭头函数则适用于特定场景。函数声明会提升(hoist),而函数表达式和箭头函数不会。
常见写法对比:
-
function foo(a, b) { return a + b; }—— 函数声明,可提前调用 -
const bar = function(a, b) { return a + b; };—— 函数表达式,必须先声明后调用 -
const baz = (a, b) => a + b;—— 箭头函数,不绑定this,不能用作构造函数
注意:function 关键字开头的是声明;等号右边带 function 或 => 的是表达式。混淆这两者容易导致 ReferenceError 或 TypeError。
参数传递是值传递还是引用传递?
JavaScript 统一按「值传递」处理,但值的类型决定了行为表现——原始类型传的是副本,对象类型传的是指向堆内存地址的副本。
立即学习“Java免费学习笔记(深入)”;
这意味着:
- 修改
number、string、boolean等原始类型参数,不影响外部变量 - 修改
obj.prop或arr.push()会影响外部对象,因为地址没变 - 但给参数重新赋值(如
obj = {})不会影响外部变量,因为只是改了本地地址副本
示例:function mutate(o) { o.x = 1; o = {y: 2}; },调用后原对象有 x 属性,但不会被替换成新对象。
如何处理不确定数量的参数?
推荐用剩余参数(...args)替代老旧的 arguments 对象,它真正是个数组,支持 map、reduce 等方法。
关键区别:
-
function f(...args) { console.log(args instanceof Array); }→ 输出true -
function f() { console.log(arguments instanceof Array); }→ 输出false(它是类数组) -
arguments在箭头函数中不可用;...args可以在任何函数中使用
注意:剩余参数必须是最后一个形参,且不能重复出现;解构时也支持类似语法,比如 const [first, ...rest] = arr。
默认参数和参数解构怎么安全使用?
默认参数在调用时才求值,支持表达式甚至函数调用;解构赋值默认值则只在对应属性为 undefined 时生效,null 不触发。
典型陷阱:
-
function f(x = y) { let y = 1; }→ 报错,y未定义(暂时性死区) -
function g({a = 0} = {}) { return a; }→ 安全,空对象作为默认实参兜底 -
g(null)会报错,因为null无法解构;应写成function g(opts = {}) { const {a = 0} = opts; }
复杂参数建议统一用单个配置对象加解构,默认值集中管理,比一堆零散参数更易维护和扩展。











