文章目录
- 什么是箭头函数 (Arrow Function)?跟一般的函数有什么差別?
- 1.语法更为简单
- 2.this值和一般函数不同
- 3.没有自己的arguments
- 4.不能作为构造函数使用
什么是箭头函数 (Arrow Function)?跟一般的函数有什么差別?
箭头函数和一般函数的主要差异有四点,我们将在下方详细说明:
- 箭头函数语法不同,写法更为简单
- 箭头函数没有自己的 this,也无法直接修改 this 指向
- 箭头函数没有自己的 arguments
- 箭头函数不能作为构造函数使用
1.语法更为简单
箭头函数相比较一般函数,语法相当简单。除了少去 function 关键字,如果只有一个参数,箭头函数可以省略括号;只有一行代码,就是直接简单返回一個变数或简单的表达式,可以省略大括号和return。例子如下:
// ES5 一般函数letaddOne=function(n){returnn+1;};// ES6 箭头函数,参数只有一个时,参数的括号可以省略letaddOne=(n)=>{returnn+1;};// ES6 箭头函式,只有一行时,省略大括号和 returnletaddOne=(n)=>n+1;2.this值和一般函数不同
配合前置查看:如何解释JavaScript 中 this 的值?
箭头函数没有自己的this值,箭头函数的this值是在一开始定义就決定,永远会是最接近自己的外层的普通函数中的this值。
此外,箭头函数也不适合使用 call、apply 和 bind 来绑定this值,绑定值会无效。
一般函数 this 绑定例子如下 :
constobj={num:100,};window.num=2020;constadd=function(a,b,c){returnthis.num+a+b+c;};//绑定 this 值为 obj,obj 的 num 为 100,所以 resultCall 是 106constresultCall=add.call(obj,1,2,3);console.log(resultCall);// 106this 绑定会无效,以下为例子
constobj={num:100,};window.num=2020;constadd=(a,b,c)=>this.num+a+b+c;// 绑定 this 无效,add 函数的 this 会是 window// 所以 num 会是 2020,resultCall 则是 2026console.log(add.call(obj,1,2,3));// 2026箭头函数根本没有自己的 this,call/apply/bind 对它不生效,非严格模式下,当前这个箭头函数 this 的上一层是 Window
利用箭头函数没有自己的this值的特性,很适合用在 setTimeout() 和 EventTarget.prototype.addEventListener() 等方法当中,因为它可以自动绑定在合适的范围中。可以看到下方setTimeout当中,用一般函数中用箭头函数的this区别:
// 一般函式版本,this 值在这个情况下是 NaNconstobj={count:10,doSomethingLater(){setTimeout(function(){// 此 function 为一般函数,因此 this 指向 windowthis.count++;console.log(this.count);// NaN (因为在 windonw 中没有 count)},300);},};obj.doSomethingLater();// 箭头函数版本constobj={count:10,doSomethingLater(){// 此 function 为箭头函数,因此 this 会依据最接近的父层一般函数的 this 值,这里为 objsetTimeout(()=>{this.count++;console.log(this.count);// 11 (obj 的 count 原本是 10,10++ 会是 11)},300);},};obj.doSomethingLater();3.没有自己的arguments
前置知识 arguments:
arguments 是“函数在运行时,自动生成的一个类数组对象”,里面保存了你调用这个函数时传入的所有实参。
当你调用一个普通函数时(不是箭头函数的时候)
function foo(a, b) { console.log(arguments); } foo(1, 2, 3); //JS 引擎会在函数内部偷偷给你一个东西: arguments = { 0: 1, 1: 2, 2: 3, length: 3 }arguments 是类数组对象,不是数组
arguments.length;// ✅arguments[0];// ✅arguments.map();// ❌拓展知识 rest参数:
arguments 是旧写法,类数组,现代写法是 剩余参数(rest parameter),得到的是真正的数组
functionfn(a,b,...rest){console.log(a);// 第一个console.log(b);// 第二个console.log(rest);// 剩下的}fn(1,2,3,4,5);12[3,4,5]// 当然了可以直接写functionfn(...rest){console.log(rest);// 剩下的}[1,2,3,4,5]箭头函数没有arguments对象,但好处是,箭头函数可以获取最近的非箭头函数的arguments对象,如下例子
constarguments=[1,2,3];constarr=()=>arguments[0];arr();// 1// 一般函数有 arguments 对象,就是传入的参数,在这个的一般函数 arguments 是 [3]// 所以 arguments[0] 也会是 3// f() 则会是 3 + 3functionfoo(n){constf=()=>arguments[0]+n;returnf();}foo(3);// 3 + 3 = 6如果需要使用到箭头函数的所有参数,可以用以下剩余参数(rest parameter)的写法得到
4.不能作为构造函数使用
箭头函数不能作为构造函数使用,换言之不能用new关键字调用,会报错
constarrowFun=()=>{};newarrowFun();// error: arrowFun is not a constructor