箭头函数
定义
箭头函数是 ES6 之后增加的一种编写函数的方法,并且它比函数表达式要更加简洁
- 箭头函数不会绑定 this、arguments 属性;
- 箭头函数不能作为构造函数来使用(不能和 new 一起来使用,会抛出错误);–> (因为箭头函数没有原型);
和普通函数对比
普通函数
1 2 3 4 5 6 7 8
| function foo1() { };
const foo2 = function (name, age) { console.log("函数体代码"); console.log(name, age); };
|
箭头函数
1 2 3 4 5
| const foo3 = (name, age) => { console.log("箭头函数函数体代码"); console.log(name, age); }
|
箭头函数简写
- 如果箭头函数只有一个参数,那么 () 可以省略
1 2 3 4 5 6 7 8 9 10
| const names =["fsllala","fsl","forward"]; const nums =[20,30,45,66,73];
names.forEach(item=>{ console.log(item); })
const newNums = nums.filter(item=>{ return item%2==0; })
|
- 如果箭头函数只有一行执行代码,那么 {} 可以省略
1 2 3 4 5 6 7
| const names = ["fsllala", "fsl", "forward"]; const nums = [20, 30, 45, 66, 73];
names.forEach(item => console.log(item))
const newNums = nums.filter(item => item % 2 == 0)
|
- 只有一行执行代码,这行代码的表达式结果会作为函数的返回值默认返回
1 2 3 4 5 6 7 8 9 10 11
| const nums = [20, 30, 45, 66, 73]; const newNums = nums.filter(item => item % 2 == 0); console.log("newNums",newNums);
const arrFn1 =()=>{ return 123; }
const arrFn = ()=>123; console.log(arrFn());
|
- 如果默认返回值是一个对象,那么这个对象必须加 ()
- 我们先看如下现象,不难发现,当函数的返回值是对象形式的时候,不能区分
{}
到底是执行体,还是返回的对象;
1 2 3 4 5
| const arrFn1 = () => 123; const arrFn2 = () => "fsllala"; const arrFn3 = () => [2, 3, 4, 5, 1]; const arrFn4 = () => { name: "fsllala" }; const arrFn5 = ()=>{}
|
- 为了区分,这个对象必须加 ();代表箭头函数的默认返回值是个对象;
1
| const arrFn4 = () => ({ name: "fsllala" });
|
箭头函数 this 指向
箭头函数不使用 this 的四种标准规则(也就是不绑定 this);箭头函数内部没有绑定自己的 this,而是根据外层作用域来决定 this;
所以箭头函数中的 this 和普通变量的查找机制一样,当前作用域没有,会向上层作用域查找;
普通函数没有这个 this 查找机制,而是遵循 this 的四种标准规则;详见:this
- 全局环境 this
1 2
| console.log("window", this);
|
- 隐式绑定
绑定改的是函数内部的 this 指向,但是箭头函数内部没有 this,会向上层作用域查找 this,但并没有改变上层作用域中的 this 指向
1 2 3 4 5 6 7 8 9
| const foo = () => { console.log(this); } const obj = { name: "fsllala", say: foo }
obj.say();
|
- 显示绑定
绑定改的是函数内部的 this 指向,但是箭头函数内部没有 this,会向上层作用域查找 this,但并没有改变上层作用域中的 this 指向
1 2 3 4 5
| const foo = () => { console.log(this); } foo(); foo.call("aaa");
|
- 箭头函数 例一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| const obj = { name: "fsllala", say: function () { const bar = () => { console.log("bar", this); } return bar } }
const fn = obj.say(); fn();
|
- 箭头函数 例二:
obj 是个对象,是没有自己的作用域的;可能有人会说 obj 是用 const 声明的,但其实块级作用域形式为 {const xxx=xxxx;}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| const obj = { name: "fsllala", say: () => { const bar = () => { console.log("bar", this); } return bar } }
const fn = obj.say(); fn();
|
- 箭头函数 例三:
模拟回调函数的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function request(url, callbackFn) { const arrs = ["fsl", "fsllala", 'forward']; callbackFn(arrs); }
const obj = { names: [], network: function () { request("/namesArr", function (params) { console.log(params); }) } }
obj.network();
|
需求:将回调函数返回的数据添加到 obj.names 中;
- methods1:const that = this;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| function request(url, callbackFn) { const arrs = ["fsl", "fsllala", 'forward']; callbackFn(arrs); }
const obj = { names: [], network: function () { const that = this; request("/namesArr", function (params) { console.log(this); that.names = [...params]; }) } }
obj.network(); console.log(obj);
|
实际操作的位置 (业务) 中讲普通函数改为了箭头函数;
1 2 3 4 5 6 7 8 9 10 11
| const obj = { names: [], network: function () { request("/namesArr", (params) => { console.log(this); this.names = [...params]; }) } }
|
整体代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| function request(url, callbackFn) { const arrs = ["fsl", "fsllala", 'forward']; callbackFn(arrs); }
const obj = { names: [], network: function () { request("/namesArr", (params) => { console.log(this); this.names = [...params]; }) } }
obj.network(); console.log(obj);
|