简单的说,箭头函数就是对匿名函数的简化
作为ES6的一种新规范,箭头函数的优点不仅在于写法上的简化,更多的是能够根据情况,与匿名函数之前切换使用,快速达到this指向切换的效果。
那么,箭头函数如何使用呢?
用法及格式
一般形式上的箭头函数长这样 (看了案例还是不明白的,可以运行代码看一下结果,或许你就明白了)
() => {
return
}
- 单参数及单语句时 (单参数,在箭头函数中参数的括号可以省略)
x => x*2
// (x) => x*2 这样写也是可以的
// 普通匿名函数
function (x) {
return x*2
}
- 多参数单语句 (多个参数,参数必须由括号括起来)
(x, y) => x*y
// 普通匿名函数
function (x, y) {
return x*y
}
- 单参数多执行语句时
x => {
if (x > 5) {
x *= 5 // x = x * 5
} else {
x = 5
}
return x
}
// 普通匿名函数
function (x) {
if (x > 5) {
x *= 5 // x = x * 5
} else {
x = 5
}
return x
}
- 多参数多执行语句
(x, y) => {
if (x > 5) {
x *= 5 // x = x * 5
y = x
} else {
y *= 5
x = y
}
return x + y
}
// 普通匿名函数
function (x, y) {
if (x > 5) {
x *= 5 // x = x * 5
y = x
} else {
y *= 5
x = y
}
return x + y
}
- 没有参数时 (参数位置必须加括号) 多语句情况同上
() => 99
// 普通匿名函数
function () {
return 99
}
- 可变参数 (利用rest取参数值)
这里扩展了知识点 rest,可以利用… 对个数不明参数的参数进行囊括。函数内,可以通过数组的方式。对rest取值,即可拿到实参。
(x, y, ...rest) =>{
let i,sum = x+y
for (i=0; i < rest.length; i++){
sum += rest[i]
}
return sum
}
// 例子 表达式函数
let fn = (x, y, ...rest) => {
let i, sum = x + y // sum = 4
console.log(rest.length) // 3
for (i = 0; i < rest.length; i++) {
sum += rest[i]
console.log(sum)
// sum += 4; sum += 5;sum += 6 4/8/13/19
console.log(typeof sum) // number
}
console.log(sum) // 19
return sum
}
const result = fn(1,3,4,5,6)
console.log(result) // 19
- 如果函数返回值是一个对象
// 这样写会出错
x => {foo:x} // 这和函数体{}有冲突
// 写成这种
x => {{foo:x}}
// 或者写成这种
x => x = {foo:x}
这些就是常见的箭头函数的写法,可用于一般类型返回值使用。 看完是不是感觉,原来箭头函数这么简单,对没错…就是如此简单。
箭头函数在一定形式上与匿名函数没有太大的差异,写法上除了函数头尾部,函数体依旧是逻辑性的代码。至于this指向的问题,请向下看 ↓
this指向理解
箭头函数的this和外部保持一致。是不是感觉很抽象? 换句话说,在箭头函数内使用this时,它的this 和在箭头函数外的this指向同一个对象。看代码:console.log(this) // window
let fun = () => {
console.log(this)
}
box.onclick = fun // this 指向 window
box.onclick = function(){
let fun = () => {
console.log(this) // this 指向 box
}
console.log(this) // this 指向 box
fun()
}
// 普通匿名函数
box.onclick = function(){
let fun = function () {
console.log(this) // this 指向window
}
console.log(this) // this 指向 box
fun()
}
- 从上面的代码,我们可以看到,在触发类型事件内,定义了一个箭头函数,它的this 指向了 事件源 box,而在改触发类型事件内定义匿名函数,它的this指向的是 全局window,这是为什么呢?
- 从概念上看,箭头this的指向和外部保持一致,此时定义的箭头函数外部,即为box的事件函数内部,而事件函数内部的this此时是指向的 box,所以console.log两次都是 box,匿名函数的this也指向了box,完成与外部保持一致。而通过匿名函数方式定义的函数的this,和定义的位置没有关系,和它的调用者有关,fun函数是通过fun()调用的,那么它的this指向的就是window,不明白没关系。 0.0, window.fun() 现在明白了没。
箭头this修改
- call方法
首个参数是this - apply方法
首个参数是this,自定义参数传入数组 - bind方法
首个参数是this,返回修改了this指向的新函数,不会立即执行
const obj = {
name:"Jack",
fn:function(a,b){
console.log(this)
console.log(a,b)
}
}
let box = document.querySelector("#box")
// 此时 由 box 点击的时候 调用该函数 所以内部的 this 指向 box
box.onclick = function(){
// obj.fn(100)
obj.fn.call(box,10,20)
}
box.onclick = obj.fn.call(box,10,20)
box.onclick = function(){
// obj.fn(100)
obj.fn.apply(box,[10,20])
}
box.onclick = obj.fn.apply(box,[10,20])
box.onclick = function(){
// obj.fn(100)
obj.fn.bind(box)
}
box.onclick = obj.fn.bind(box)
// 现在 res 相当于一个 已经改变了 this 指向的新函数
let res = obj.fn.bind(box)
res(10,20)
obj.fn.bind(box)(10,20)
// console.log(res)
与普通函数的区别
- 箭头函数形式上做了改变,简化了函数体。
- 普通函数支持通过arguments 获取未知个数的实参,而箭头函数不支持arguments用法。
- 箭头函数在es6标准下可使用,普通函数则没有这个限制。
- this指向的修改。箭头函数的this指向外部,常在对类的方法进行构造时使用,使函数体内的this始终指向这个类。如果需要this指向当前源,则可使用普通函数。