箭头函数:
作用: 箭头函数表达式更适用于那些本来需要匿名函数的地方,比如回调函数
使用方法:
(param1,param2,…) =>{ statements }
支持剩余参数和默认参数,支持参数列表解构
普通函数与箭头函数用法比较:
如返回数组中每一项字符串的长度
//普通函数
let arr=['heiuwo','eiswoeif','ciwove']
arr.map(function (item) {
console.log(item.length)//循环打印 6 8 6
})
//箭头函数
arr.forEach((item,index)=>{
arr[index]='箭头函数'
})
当箭头函数的函数体内只有一条语句或 return 语句时可以省略return关键字和 {}
上例中的箭头函数可以写成如下形式:
//当箭头函数的函数体内只有一条语句或 return 语句时可以省略return关键字和 {}
arr.forEach((item,index)=> arr[index]='箭头函数')
console.log(arr)//["箭头函数", "箭头函数", "箭头函数"]
如果需要返回对象时:加括号的函数体可以返回对象字面量表达式
只有一个返回对象的语句可以在外层加 () 括号,否则解析会出错,将对象的{}当作函数体。
let func = (id,name)=>({'id':id,'name': name})
console.log(func(1,'obj'))//{id: 1, name: "obj"}
箭头函数的特点和使用注意事项:
箭头函数没有自己的 this
,arguments
,super
或 new.target
。且它不能用作
构造函数
所以也不能用 new关键字
调用,也没有 原型 prototype
。
1. 箭头函数没有 this
箭头函数没有 this,只会从自己的作用域链上继承上一层作用域的 this,所以箭头函数也不能使用 call apply bind 方法来改变 this 指向,第一个参数会忽略无效。
而普通函数是根据被调用时的环境来确定 this ,下面例子实现点击按钮后按钮禁用,3 秒后开启按钮。通过实例观察箭头函数 this 的继承关系。
var btn=document.querySelector('button')
btn.onclick=function () {
this.disabled=true
setTimeout(()=>{
this.disabled=false
},3000)
}
一般情况下,定时器回调函数是 普通函数
时 this 指向的是 window ,所以想要获取 btn 的 disabled 属性需要要改变 this 。
而箭头函数因为继承其作用域链上一层作用域的 this 正是 btn.onclick 函数作用域内的this ,不需要改变。
看第二个例子观察箭头函数继承的 this
的变化:
let name='window'
let obj={
name:'Obj',
show:function () {
console.log('普通函数调用时的this:'+this.name)
let f=()=>{
console.log('f箭头函数继承的this:'+this.name)
}
f()
}
}
//1、对象调用,输出 obj
obj.show()
//2、直接调用,输出 window
let fn = obj.show
fn()
2. 不绑定 arguments
箭头函数没有自己的 arguments 对象,如下面例子无法访问到 arguments
let f=(a,b) => {
console.log(arguments[0])//ReferenceError: arguments is not defined
}
f(4,5)
但是 箭头函数可以引用封闭作用域内的 arguments,即因为其外部非箭头函数的 arguments:
function add(...arg) {
let f=() => {
console.log(arguments[0])//引用外部函数 arguments
}
f()
console.log(arguments)//打印的是add 函数传递的arguments对象,是一个伪数组对象
}
add(1,2,3,4,5)
add(1,2,3)
输出结果:
3. 不能用作构造函数,没有 prototype
箭头函数不能用作构造函数,没有 prototype,使用 new 关键字调用会报错
var Foo=(a)=>{
this.a=a
}
console.log(Foo.prototype)//undefined
//var obj=new Foo('obj')//TypeError:Foo is not a constructor
4. 没有 new.target 和 super
因为不能使用 new 调用,所以也没有 new.target 值。
new.target 属性可以检测函数或构造方法是否是通过 new 运算符被调用的。在通过 new 运算符被初始化的函数或构造方法中,new.target 返回一个指向构造方法或函数的引用。在普通的函数调用中,new.target 的值是undefined。
关于 new.target,可以参考 阮一峰-ECMAScript 6 入门和 MDN-new.target
箭头函数没有原型,所以也不能通过 super 来访问原型的属性,是没有 super 的。