普通函数用function关键字定义,支持命名、匿名、IIFE等形式,具this/arguments动态绑定且会被提升;箭头函数是语法糖,不绑定this/arguments,适合词法绑定场景,不可作构造函数。
function 关键字是基础JavaScript 里最常规的函数定义方式,就是用 function 关键字。它支持命名、匿名、立即执行等多种形式,也允许在函数体内使用 this、arguments 和 new.target 等动态绑定特性。
常见写法示例:
function add(a, b) {
return a + b;
}
const multiply = function(x, y) {
return x * y;
};
// 立即执行函数表达式(IIFE)
(functio
n() {
console.log('run once');
})();
注意点:
function 声明会**提升(hoist)**,可以在定义前调用;而 function 表达式不会this 值取决于**调用方式**(如 obj.fn() 中 this 指向 obj),不是定义位置arguments 对象可访问传入的所有参数,箭头函数里没有这个对象this?它不绑定执行上下文箭头函数(() => {})本质是函数表达式的语法糖,但它**不创建自己的 this、arguments、super 或 new.target**——这些全部从外层作用域继承。所以它不能用作构造函数(调用会报 TypeError: xxx is not a constructor),也不能用 call/apply/bind 改变 this。
典型误用场景:
this 指向外层,不是当前对象arguments 处理不定参数 → 箭头函数里根本不存在 arguments
正确替代方式:
const obj = {
value: 42,
// ❌ 错误:this 指向外层(通常是 global 或 undefined)
badMethod: () => console.log(this.value),
// ✅ 正确:普通函数,this 指向 obj
goodMethod() {
console.log(this.value);
},
// ✅ 箭头函数可用在需要稳定 this 的地方(如 setTimeout 回调)
delayedLog() {
setTimeout(() => {
console.log(this.value); // this 正确继承自 delayedLog 的调用上下文
}, 100);
}
};
=> 写法有哪些简写规则?参数和返回值可以省略括号和花括号箭头函数的语法灵活,但省略规则有明确优先级:单参数可省 (),单表达式可省 {} 和 return,但一旦涉及多语句、解构、默认参数或需要显式返回对象字面量,就必须加括号或花括号。
常见写法对比:
x => x * 2 → 单参数 + 单表达式,隐式返回(x, y) => x + y → 多参数必须加 ()
x => ({ id: x }) → 返回对象字面量,必须用小括号包裹,否则会被解析为代码块([a, b]) => a + b → 参数解构必须加 ()
(x = 1) => x → 默认参数也必须加 ()
容易踩坑的写法:
// ❌ 你以为返回 { name: 'Alice' },实际返回 undefined(被当成了代码块)
x => { name: 'Alice' }
// ✅ 正确写法:用括号包裹对象字面量
x => ({ name: 'Alice' })
// ✅ 或者显式写 return
x => { return { name: 'Alice' }; }
箭头函数不是“更现代的替代品”,而是解决特定问题的工具:**需要词法绑定 this 和 arguments 的场景**。它适合用在回调、闭包、高阶函数参数里;不适合用在对象方法、原型方法、构造器、事件处理器(除非你明确控制了 this 绑定)。
判断依据很简单:
this 指向调用者?→ 用普通函数this 和外层一致(比如类中方法内嵌的定时器回调)?→ 用箭头函数new 调用?→ 只能用普通函数性能上几乎没有差异,但语义清晰更重要。混淆两者最常导致的 bug 是:对象方法意外写成箭头函数后,this 变成 undefined,访问属性时报 Cannot read property 'xxx' of undefined。