为什么叫箭头函数(Arrow Function)
请看一个实例:
x => x * x
由上面函数可知,它的确含有一个箭头,故名箭头函数。
注: ’ = ’ 与 ’ > ’ 之间不可有空格。
上面箭头函数等价于:
function (x) {
return x * x;
}
初步使用
其实,箭头函数近似于(实际上有区别)匿名函数,简化了函数定义.
箭头函数有两种格式:
1. 仅有一个表达式,可以省略 `{ }`和 `return`,如上面的箭头函数。
2. 当有多个表达式,不可省略 `{ ... }`和 `return`,如:
x => {
if (x > 0) {
return x;
}
else {
return -x;
}
}
若形参为0个或多个时,需要使用括号,如:
(x, y) => x * y
若返回一个对象,需用括号,如:
var obj = x => ({ name: x })
console.log(obj('zq').name) // zq
this
箭头函数与匿名函数的区别就在于this
箭头函数内部的this
是内部作用域,由上下文确定。
this 指向上一级作用域所在的对象。
(对象不形成一级作用域,函数形成一级作用域)
故,用call()
或者apply()
调用箭头函数时,无法对this
进行绑定,即传入的第一个参数被忽略:
var obj = {
birth: 1990,
getAge: function (year) {
var b = this.birth; // 1990
var fn = y => y - this.birth; // this 指向 obj, birth仍是1990
return fn.call({birth:2000}, year);
}
};
obj.getAge(2015); // 25
不能使用箭头函数的情况
1. 定义对象方法
var test = {
arr: [1, 2, 3],
sum: () => {
console.log(this === window); // true
return this.arr.reduce((result, item) => result + item)
}
}
test.sum();
//报错 TypeError: Cannot read property 'reduce' of undefined
分析: 对象方法内部的this
指向的是外部对象,但是使用箭头函数时,this
指向window。
解决方法: 使用函数表达式或方法简写来定义对象方法,确保this
由运行时包含它的上下文所决定。
var test = {
arr: [1, 2, 3],
sum() {
console.log(this === test); // true
return this.arr.reduce((result, item) => result + item)
}
}
test.sum();// 6
2. 定义原型方法
function Person(name) {
this.name = name;
}
Person.prototype.log = () => {
console.log(this.name);
};
Person.prototype.log2 = function() {
console.log(this.name);
};
let p = new Person("ZQ");
let name = "window";
p.log(); // "window"
p.log2(); // "ZQ"
let log = p.log2;
log(); // "window"
// 等价于 window.log(), this 指向是调用该方法的对象
3. 动态上下文中避免使用箭头函数
document.querySelectorAll('p').forEach(elem => {
elem.addEventListener('click', () => {
console.log(this.innerText.length) // 这个时候 this 指向 window,因此会报错
})
})
document.querySelectorAll('p').forEach(elem => {
elem.addEventListener('click', function() {
console.log(this.innerText.length) // 这个时候 this 指向 elem
})
})
参考资料