一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情。
箭头函数的基本使用与注意点
基本用法
箭头函数是es6里新增加的语法糖;
在es6之前我们定义返还函数可以通过以下方式来实现:
var fun=function(arg){
return arg;
}
console.log(fun('123')); //123
在es6中我们通过箭头函数让其变得更加的简单,如下:
var fun=arg=>arg;
console.log(fun('123')); //123
箭头函数最大的特点就是有箭头“=>” 符号,它有很多变式写法:
- 没有参数时,用括号()代替;
- 一个参数时,括号可以省略;
- 多个参数时,(arg1,agr2...)
如下:
//没有参数时,用括号()代替;
var fun=()=>'123';
console.log(fun()); //123
//一个参数时,括号可以省略;
var fun=arg=>arg;
console.log(fun('123')); //123
//多个参数时;
var fun=(arg1,arg2)=>arg1+arg2;
console.log(fun(1,5)); //6
也可以手动返回数据;
var fun=arg=>{
return arg;
};
console.log(fun('123')); //123
注意点
注意点1:利用箭头函数隐式返回的时候需要注意,数据是对象时的情况,比如以下错误的情况:
var fun=arg=>{
name:'静静',
age:18
};
这里返回数据实际上是个对象,但是它的大括号和函数本身的大括号有冲突,系统会默认为是函数的大括号,导致报错。所以应改为如下:
var fun=arg=>{{
name:'静静',
age:18
}};
console.log(fun()); //{name:'静静',age:18}
注意点2:箭头函数里没有this绑定,如下代码,箭头函数里面的this指向对象本身:
var obj={
name:'静静',
age:18,
fun:function(){
console.log(this.name);//静静
}
}
obj里fun的this指向obj,所以能找到name, 现将obj里面的fun函数改成箭头函数,会发生什么?
var obj={
name:'静静',
age:18,
fun:()=>{
console.log(this.name);//undefined
}
}
因为箭头函数fun里面没有this绑定,因此箭头函数会指向最近的的上层this,所以这里的this指向的是window,因此找不到name的值。
注意点3:没有隐藏参数arguments的绑定;
使用箭头函数时还须注意没有参数arguments的绑定,看如下代码:
var fun=(arg1,arg2)=>{
console.log(arguments);//arguments is not defined
return arg1+arg2
};
console.log(fun(1,5)); //6
箭头函数的重要特征
重要特征:箭头函数可让函数内的this与函数外的this保持一致;
因为箭头函数里没有this绑定,箭头函数会指向最近的的上层this,所以说:箭头函数可让函数内的this与函数外的this保持一致。
什么情况下使用箭头函数
如果函数中不包含this,或刚好希望函数内的this与外部this保持一致时,就可以改为箭头函数;
如果反而不希望函数内的this与函数外的this保持一致时,都不能改成箭头函数;
误区
箭头函数没有、不是作用域,这是错误错误错误的,重要的事说三遍。
箭头函数只让this,指向外部作用域的this,而箭头函数内的局部变量,依然只能在箭头函数内使用,出了箭头函数不能用,所以,箭头函数依然是作用域,只不过影响this而已,不影响局部变量;
箭头函数底层原理
有没有发现一个问题:把函数改成bind效果和箭头函数的效果一样?! 看如下代码:
var obj={
name:'静静',
age:18,
friends:['小明','小红','小月'],
fun:function(){
console.log(`fun里面的this=====>${JSON.stringify(this)}`);
//this.fiends:['小明','小红','小月']
this.friends.forEach(
function(friend){
//this.name为undefined
console.log(`forEach里面的函数this=====>${this}`);
console.log(`${this.name}的朋友是${friend}`);
}
)
}
}
obj.fun();
看输出:
fun里面this.friedns值为:
['小明','小红','小月'],this指的是obj,但是ForEach里面function的this指向window,因此没有找到name值,值为undefined。我们如果给function加个bind会怎么样,看如下代码:
var obj={
name:'静静',
age:18,
friends:['小明','小红','小月'],
fun:function(){
console.log(`fun里面的this=====>${JSON.stringify(this)}`);
//this.fiends:['小明','小红','小月']
this.friends.forEach(
function(friend){
//this.name为undefined
console.log(`forEach里面的函数this=====>${JSON.stringify(this)}`);
console.log(`${this.name}的朋友是${friend}`);
}.bind(this)
)
}
}
obj.fun();
看下输出:
发现加上bind后,this指向变了,this指向了obj,我们再看一下,改成箭头函数,代码如下:
var obj={
name:'静静',
age:18,
friends:['小明','小红','小月'],
fun:function(){
console.log(`fun里面的this=====>${JSON.stringify(this)}`);
//this.fiends:['小明','小红','小月']
this.friends.forEach(
(friend)=>{
//this.name为undefined
console.log(`改成箭头函数后:forEach里面的函数this=====>${JSON.stringify(this)}`);
console.log(`${this.name}的朋友是${friend}`);
}
)
}
}
obj.fun();
看下输出:
forEach里面的函数this指向也变成了obj;
forEach里面的函数,无论是加bind,还是写成箭头函数,他们的this指向是一样的,效果也是一样的,所以说:箭头函数底层相当于.bind(); 永远绑定外部this;
所以call无法替换箭头函数中的this;
总结
- 箭头函数是es6里面的新语法,返回对象时,不要省略函数的大括号,因为,系统默认对象的大括号就是函数的大括号,会导致报错;
- 箭头函数没有this的绑定,也没有隐藏参数arguments的绑定;
- 箭头函数可让函数内的this与函数外的this保持一致;
- 箭头函数是有自己作用域的,本身是一个作用域;
- 箭头函数的底层原理:底层相当于.bind(),并且永远绑定外部的this,因此,call无法替换箭头函数中的this;