# (三)箭头函数
# 一、基本用法
先来看看 ES5 中我们怎么写一个函数
const foo = function (num) {
return num + 1;
};
再来看看 ES6 为我们提供的箭头函数
const foo = (num) => num + 1;
看这个例子难道箭头函数是为了让我们的代码看上去更“高大上”吗?
# 1.1 多参数
let foo = (value, num) => value * num;
# 1.2 返回一个对象
let foo = (value, num) => ({ total: value * num });
# 1.3 简化回调函数
const data = [
{ name: "yg1", age: 1 },
{ name: "yg2", age: 2 },
{ name: "yg3", age: 3 },
{ name: "yg4", age: 4 },
];
const res = data.map(({ name, age }) => ({ name, age: age + 1 }));
# 2.区别
抛开优雅的代码,我们仍要知道箭头函数和普通函数的区别在哪里
# 2.1 没有 this
- 箭头函数没有 this,所以需要通过查找作用域链来确定 this 的值。
- 箭头函数中的 this,就绑定在它最近一层非箭头函数的 this.
一句话理解:箭头函数内部的 this 是词法作用域,由上下文确定。
我们来看这样一段代码:
const obj = {
name: "111",
foo: function () {
console.log(this.name);
const b = function () {
console.log(this.name);
};
b();
},
};
obj.foo();
- 第一个函数字面量在作为对象的方法被调用时。this 指向对象
- 第二个函数正常调用时指向全局对象——window
同样的代码结构,我们来看一下改造后的代码:
const obj = {
name: "111",
foo: function () {
console.log(this.name);
const b = () => {
console.log(this.name);
};
b();
},
};
obj.foo();
- 第一个函数字面量 foo 在作为对象的方法被调用时。this 指向对象
- 第二个箭头函数 b,它的 this 绑定在最近一层非箭头函数,也就是 obj 上
# 2.2 没有 arguments
箭头函数没有自己的 arguments
对象,这不一定是件坏事,因为箭头函数可以访问外围函数的 arguments 对象:
function constant() {
return () => arguments[0];
}
var result = constant(1);
console.log(result()); // 1
那如果我们就是要访问箭头函数的参数呢?
你可以通过命名参数或者 rest 参数的形式访问参数:
let nums = (...nums) => nums;
# 2.3 不能通过 new 关键字调用
JavaScript 函数有两个内部方法:[[Call]]
和 [[Construct]]
。
当通过 new 调用函数时,执行 [[Construct]]
方法,创建一个实例对象,然后再执行函数体,将 this 绑定到实例上。
当直接调用的时候,执行 [[Call]]
方法,直接执行函数体。
箭头函数并没有 [[Construct]]
方法,不能被用作构造函数,如果通过 new 的方式调用,会报错。
大致了解了箭头函数以后,我们来看下面的例子:
function foo() {
return () => {
return () => {
return () => {
console.log("id:", this.id);
};
};
};
}
上面代码之中,只有一个this,就是函数foo的this。
# 三、总结
最后,关于箭头函数,引用 MDN 的介绍就是:
An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or new.target. These function expressions are best suited for non-method functions, and they cannot be used as constructors.
翻译过来就是:
箭头函数表达式的语法比函数表达式更短,并且不绑定自己的 this,arguments,super 或 new.target。这些函数表达式最适合用于非方法函数(non-method functions),并且它们不能用作构造函数。
那么什么是 non-method functions 呢?
我们先来看看 method 的定义:
A method is a function which is a property of an object.
对象属性中的函数就被称之为 method,那么 non-mehtod 就是指不被用作对象属性中的函数了,可是为什么说箭头函数更适合 non-method 呢?
让我们来看一个例子就明白了:
var obj = {
i: 10,
b: () => console.log(this.i, this),
c: function () {
console.log(this.i, this);
},
};
obj.b();
// undefined Window
obj.c();
// 10, Object {...}
从表现上来看,它也是 non-method ~
# 参考
写在最后
JavaScript 系列:
- 《JavaScript 内功进阶系列》(已完结) (opens new window)
- 《JavaScript 专项系列》(持续更新) (opens new window)
- 《ES6 基础系列》(持续更新) (opens new window)
关于我
- 花名:余光(沉迷 JS,虚心学习中)
- WX:j565017805
其他沉淀
如果您看到了最后,对文章有任何建议,都可以在评论区留言
这是文章所在 GitHub 仓库的传送门 (opens new window),如果真的对您有所帮助,希望可以点个 star,这是对我最大的鼓励 ~