箭头函数就是更短的函数写法,而且 this 继承外层不自己绑定。
核心规则:
① 写法——() => {} 省略 function
② 单参数省略括号——x => x*2
③ 单表达式省略 return——x => x*2
④ this 继承外层
坑:箭头函数没有自己的 this、不能当构造函数、没有 arguments、不能用 yield。
同样是"两个数相加",function 要写一整行,=> 一条语句直接连返回值都省了。
// 以前:正式合同,要写 function 和 return
// 普通函数:关键字 function + 花括号
let sum = function (a, b) {
// 算完还得自己写 return
return a + b;
// 现在:一张便签 (参数) => 结果
};
// 只有一条语句时,{} 和 return 都能省,结果自动返回
let sum = (a, b) => a + b;
什么时候能省括号、什么时候必须写花括号?记住:一个参数省括号,一条语句省 return。
// 0 个参数:括号不能省(空括号也得留着)
// 1 个参数:括号可以省掉,最省事
let say = () => console.log("hello");
// 多个参数:括号必须有(不然不知道从哪开始)
let hi = name => "hello " + name;
// 多条语句:{} 和 return 都不能省
let add = (a, b) => a + b;
let calc = (a, b) => {
// 第一条
let s = a + b;
// 第二条,必须手动 return
return s * 2;
};
如果你只有一个参数却还是写了括号,程序不会报错,只是没省到;反过来,如果你写多条语句却省了花括号和 return,就会直接报错。因为便签只能写一行——多写几行就必须用花括号包起来并自己写 return。
function 的 this 看"谁调用它"——像看"这张合同是谁签的字";箭头函数 的 this 看"它写在哪一层"——像便签上自带的地址,搬到哪都不变。
// 造一个对象,里面有个名字
let obj = {
// 对象自己的名字
name: "大喇叭",
// function:this 看"谁调用",在 setTimeout 里 this 变成 window
// 普通方法
say1: function () {
// 套一个普通函数当定时器回调
setTimeout(function () {
// undefined(this 已经跑到 window 去了)
console.log(this.name);
}, 100);
// 箭头函数:this 看"写在哪",就是外层那个 obj
},
// 外层还是普通 function(this 指 obj)
say2: function () {
// 里面套箭头函数
setTimeout(() => {
// 大喇叭(this 还指着 obj)
console.log(this.name);
}, 100);
}
};
如果你在定时器、事件回调里还想用外层对象的 this,就用箭头函数;如果你想自己拿一个新的 this(比如事件里要读 e.target 对应的元素),就必须用 function。以前为了在 setTimeout 里保住 this,大家都得先写一句 let that = this 过渡——箭头函数把这个"绕弯"彻底省掉了。
便签就是便签,不能当"合同模板"去批量生产对象。
// new Foo;
let Foo = () => {};
// ★ 报错:Foo is not a constructor(不能当构造函数)
// 箭头函数里根本没有 arguments 这个变量
let f = () => arguments;
// 想拿全部参数,改用 rest:(...args) => ...
如果你试图 new 一个箭头函数,浏览器会直接报错"不是构造函数"。因为箭头函数没有自己的 prototype、没有自己的 this、也没有 arguments——它就是一张纯便签,不适合当"造对象的模具",也不适合做需要动态 this 的对象方法。
① 可能在什么地方用:.map/.filter 回调、setTimeout/setInterval 里要拿外层 this、React/Vue 里传回调、简短的一行工具函数。
② 常见的问题:把箭头函数当对象方法导致 this 不符合预期;new 箭头函数直接报错;箭头函数里读 arguments 是 undefined。
③ 解决思路:要动态 this(如事件里拿 e.target)就用普通 function;要绑外层 this 就用箭头函数;拿全部参数用 (...args) =>;千万别 new 箭头函数。
| API | 作用 | 参数 | 返回值 | 代码示例 |
|---|---|---|---|---|
| (a, b) => a + b | 短写函数,只有一条语句时自动返回结果 | 参数列表 | 一个函数 | let f = (a, b) => a + b; |
| => 里的 this | 箭头函数没有自己的 this,锁在定义处外层 | - | 外层的 this | let f = (a, b) => a + b; |