箭头函数的使用注意事项
js中this的使用一直以来都比较难以理解,和php相比要复杂许多。自从ES6中新增了箭头函数的API,this的使用情况变得更加复杂。这里做几点简单的对比~
主要资料参考自大神阮一峰翻译的:阮一峰ES6教程
1, 箭头函数没有prototype(原型),所以箭头函数本身没有this,也就不能用call()、apply()、bind()这些方法去改变this的指向。
let a = () => {};
console.log(a.prototype); // undefined
2, 箭头函数的this指向在定义的时候继承自外层第一个普通函数的this。如果箭头函数外层没有普通函数,它的this会指向window(全局对象)
function test() {
this.type = 'cat'
this.obj = {
name: 'tom',
getType: () => {
return this.name + ',' + this.type
},
getName: function () {
return this.name + ',' + this.type
}
}
}
let t = new test()
console.log(t.obj.getType())
console.log(t.obj.getName())
// "undefined,cat"
// "tom,undefined"
值得注意的是:如果外层的普通函数的this指向发生改变,箭头函数的this跟着会发生改变。
3,函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
var id = 21;
foo.call({ id: 42 });
// id: 42
本例通过call()方法替换了foo()的上下文context,使foo的this指向了新的对象。由于setTimeout 的参数为一个箭头参数,它的生效时间是在100毫秒之后,箭头函数输出了42
4, 箭头函数没有constructor,使用new调用箭头函数都会报错
let a = () => {};
let b = new a(); // a is not a constructor
同是也无法使用new.target
更多移步:阮一峰ES6教程 -- new-target-属性
5, 箭头函数的arguments
第一种情况:箭头函数的this指向全局对象,会报arguments未声明的错误。
第二种情况是:箭头函数的this如果指向普通函数,它的argumens继承于该普通函数。
let foo = () => {
console.log(arguments);
};
foo(1, 2, 3, 4); // Uncaught ReferenceError: arguments is not defined
function foo() {
setTimeout(() => {
console.log('args:', arguments);
}, 100);
}
foo(2, 4, 6, 8)
// args: [2, 4, 6, 8]
可以使用rest参数(扩展运算符...)来获取函数的不定数量参数
let foo = (first, ...rest) => {
console.log(first, rest) // 1 [2, 3, 4]
};
foo(1, 2, 3, 4)