什么时候不能使用箭头函数呢?

  1. 定义对象方法
  2. 定义原型方法
  3. 定义构造函数
  4. 定义事件回调函数

首先,在定义对象方法中,举例:

1
2
3
4
5
6
7
8
9
10
11
12
const calculator = {
array: [1, 2, 3],
sum: () => {
console.log(this === window); // => true
return this.array.reduce((result, item) => result + item);
}
};

console.log(this === window); // => true

// Throws "TypeError: Cannot read property 'reduce' of undefined"
calculator.sum();

 如上,它会报错,因为 this 的指向不对,需要修改为:

1
2
3
4
5
6
7
8
const calculator = {
array: [1, 2, 3],
sum() {
console.log(this === calculator); // => true
return this.array.reduce((result, item) => result + item);
}
};
calculator.sum(); // => 6

然后,在定义原型方法上,也需要注意不能滥用箭头函数:

1
2
3
4
5
6
7
8
9
10
11
function Cat(name) {
this.name = name;
}

Cat.prototype.sayCatName = () => {
console.log(this === window); // => true
return this.name;
};

const cat = new Cat('Mew');
cat.sayCatName(); // => undefined

 这里需要修改为:

1
2
3
4
5
6
7
8
9
10
11
function Cat(name) {
this.name = name;
}

Cat.prototype.sayCatName = function () {
console.log(this === cat); // => true
return this.name;
};

const cat = new Cat('Mew');
cat.sayCatName(); // => 'Mew'

接着,在定义事件回调函数时,也需要注意 this 的指向:

1
2
3
4
5
const button = document.getElementById('myButton');
button.addEventListener('click', () => {
console.log(this === window); // => true
this.innerHTML = 'Clicked button';
});

 修正为:

1
2
3
4
5
const button = document.getElementById('myButton');
button.addEventListener('click', function() {
console.log(this === button); // => true
this.innerHTML = 'Clicked button';
});

 最后,在定义构造函数上:

1
2
3
4
5
const Message = (text) => {
this.text = text;
};
// Throws "TypeError: Message is not a constructor"
const helloMessage = new Message('Hello World!');

 修正为:

1
2
3
4
5
const Message = function(text) {
this.text = text;
};
const helloMessage = new Message('Hello World!');
console.log(helloMessage.text); // => 'Hello World!'