什么时候不能使用箭头函数?
1、定义对象方法
JS中对象方法的定义方式是在对象上定义一个指向函数的属性,当方法被调用的时候,方法内的this就会指向方法所属的对象。
1.1定义字面量方法
//1.定义字面量方法 const calculator = { array:[1,2,3], sum: ()=>{ console.log(this,window); return this.array.reduce((result, item) => result+item); } } console.log(this,window); calculator.sum()
因为运行的时候this.array未定义,调用calculator.sum时,执行上下文里的this仍指向的是window,原因是箭头函数把函数上下文绑定到了window上,this.array==window.array,后者又是未定义,所以会报错。
解决办法是使用普通函数,这样可以确保this是在运行时由包含它的上下文决定的:
const calculator = { array:[1,2,3], sum(){ console.log(this,window); return this.array.reduce((result, item) => result+item); } } console.log(this,window); calculator.sum();
1.2 定义原型方法
定义原型方法时,使用箭头函数会导致运行时的执行上下文错误
let Cat = (name)=>{ this.name = name; } Cat.prototype.sayCatName = ()=>{ console.log(this, window); return this.name; } const cat = new Dat('Kitty'); cat.sayCatName();//undefined
let Cat = function(name){ this.name = name; } Cat.prototype.sayCatName = function(){ console.log(this, window); return this.name; } const cat = new Cat('Kitty'); cat.sayCatName();//undefined
1.3 定义事件回调函数
箭头函数定义的上下文是不能改的,这样执行的时候this就等同于window,这样的话是没有任何意义的
var btn = document.getElementById('btn'); btn.addEventListener('click',()=>{ console.log(this, window); this.innerHTML = 'click btn'; })
btn.addEventListener('click',function(){ console.log(this, window); this.innerHTML = 'click btn'; })
1.4 定义构造函数
const Book = (name)=>{ this.name = name; } const book = new Book('John'); console.log(book.name);//arrow.html:75 Uncaught TypeError: Book is not a constructor
const Book = function(name){ this.name = name; } const book = new Book('John'); console.log(book.name);
1.5 追求过短的代码
刻意追求过短的代码,可能会给代码阅读和逻辑理解带来困难。
const multiply = (a, b) => b === undefined ? b => a * b : a * b; const double = multiply(2); double(3); // => 6 multiply(2, 3); // => 6
function multiply(a, b) { if (b === undefined) { return function (b) { return a * b; } } return a * b; } const double = multiply(2); double(3); // => 6 multiply(2, 3); // => 6