JavaScript函数定义有三种方式:函数声明可提升,函数表达式和箭头函数不可提升;基本类型传值、对象传引用副本;rest参数替代arguments;默认参数仅对undefined生效;箭头函数无arguments和独立this。

JavaScript 函数定义的三种常见写法
函数定义不是只有一种方式,实际项目里得看场景选:需要提升(hoisting)就用函数声明;要当值传递或避免变量污染就用函数表达式;箭头函数则适合简短逻辑和绑定 this 场景。
容易踩的坑是误以为所有函数都能被提升——只有 function foo() {} 这种声明式写法才支持,const foo = function() {} 和 const foo = () => {} 都不行,调用写在定义前会报 ReferenceError。
- 函数声明:
function add(a, b) { return a + b; } - 函数表达式:
const add = function(a, b) { return a + b; }; - 箭头函数:
const add = (a, b) => a + b;
参数传递:值 vs 引用,以及 rest 参数怎么用
JS 里没有真正的“引用传递”,只有“按共享传递”:基本类型(number、string、boolean 等)传的是值的副本;对象和数组传的是引用的副本——改属性会影响原对象,但重新赋值不会。
想接收不定数量参数?别再用 arguments(它不是真数组,且箭头函数里不可用),直接上 ... rest 参数:
立即学习“Java免费学习笔记(深入)”;
function sum(...nums) {
return nums.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3); // → 6
- rest 参数必须是最后一个形参
- 不能和多个同名参数共存(如
(a, ...rest, b)会报错) - 调用时传空参数,
nums是空数组,不是undefined
默认参数的陷阱:为什么 undefined 触发,null 不触发?
默认参数只在传入的值是 undefined 时生效。传了 null、0、false 或空字符串,都会被当作有效值,跳过默认逻辑。
这和常见的“falsy 判断”直觉冲突,比如写 function greet(name = 'Guest') { ... },调用 greet(null) 得到的是 null,不是 'Guest'。
- 安全写法:用逻辑运算符兜底,如
name = name ?? 'Guest'(ES2020 起支持 nullish 合并) - 或者显式检查:
name = name === undefined ? 'Guest' : name - 默认参数表达式每次调用都执行,不是定义时求值
箭头函数没有 arguments,也没有自己的 this
如果函数体里用了 arguments,千万别写成箭头函数,否则运行时报 ReferenceError: arguments is not defined。同样,箭头函数不绑定 this,它的 this 指向外层作用域——这对事件回调或定时器有用,但对方法定义可能是坑。
- 类方法若写成箭头函数:
class A { fn = () => { console.log(this); } },那它永远指向实例,无法被正确绑定 - 需要动态
this的场景(如 jQuery 回调、addEventListener),优先用普通函数 - 想用箭头函数又需参数对象?用 rest 参数替代
arguments,如(...args) => args[0]
.map 或 .length 上。加个简单守卫(如 if (!Array.isArray(arr)) throw new TypeError('arr must be array'))比靠注释或文档更可靠。











