10分钟理解ES6箭头函数

return result;

};

当有多条语句时,需要配上 {...}return

另外,如果返回的结果是对象,则需要配上 (),像下面这样:

const func = val => ({ value: val });

从上述的写法来看,相较普通函数而言,箭头函数的确简便了很多,提升了我们代码的易用性。但它并非在任何场景下都适用,接下来,将会介绍几种不适合箭头函数的场景,并会提出可行的解决方案。

不适合的场景


1、对象的方法

看下面这个例子:

const obj = {

x: 1,

print: () => {

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

console.log(this.x); // undefined

}

};

obj.print();

this.x 打印出来是 undefined。为什么?然后,我在上面加了一行,发现 this 指向了 window。

解析:print 方法用了箭头函数,其内部的 this 指向的还是上下文 window,上下文中并没有定义 x,所以 this.x 输出为 undefined。

解决办法:用 ES6 的短语法,或者传统的函数表达式都可以。所以,print 要这样写:

print () {

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

console.log(this.x); // 1

}

2、原型方法

同样的规则也适用于原型方法的定义,使用箭头函数会导致运行时的执行上下文错误。

function Cat (name) {

this.name = name;

}

Cat.prototype.sayCatName = () => {

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

return this.name;

};

const cat = new Cat(‘Miao’);

cat.sayCatName(); // => undefined

解决办法是:用回传统的函数表达式,像下面这样:

Cat.prototype.sayCatName = function () {

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

return this.name;

};

sayCatName 变回传统的函数表达式之后,被调用时的执行上下文就会指向新创建的 cat 实例。

3、事件的回调

看下面这个例子:

const btn = document.getElementById(‘myButton’);

btn.addEventListener(‘click’, () => {

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

this.innerHTML = ‘Clicked button’;

});

这里会有问题,因为 this 指向了 window。

解析:当为一个 DOM 事件绑定回调函数后,触发回调函数时的 this,需要指向当前发生事件的 DOM 节点,也就是这里的 btn。当回调发生时,浏览器会用 btn 的上下文去调用处理函数。所以最后的 this.innerHTML 等价于 window.innerHTML,问题就在这里。

解决办法:用函数表达式代替箭头函数。像这样:

btn.addEventListener(‘click’, function() {

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

this.innerHTML = ‘Clicked button’;

});

另外,在 react 中的事件回调,也经常会遇到类似的问题。

// jsx render

// callback

handleClickButton () {

}

注意:这里 onClick 的回调函数,并非字符串,而是一个实实在在的函数。可以将 onClick 理解为一个中间变量,所以 react 在处理函数时的 this 指向就会丢失。

为了解决这个问题,我们需要为回调函数绑定 this,使得事件处理函数无论如何传递,this 都指向我们实例化的那个对象。

在这里,如果用箭头函数,可以这样改写:

<Button onClick={ event => this.handleClickButton(event) }>

箭头函数并没有自己的 this,所以事件处理函数的调用者并不受影响。

4、构造函数

箭头函数不能通过 new 关键字调用。

const Message = (text) => {

this.text = text;

};

var helloMessage = new Message(‘Hello World!’);

// Uncaught TypeError: Message is not a constructor

解析:从报错信息可以看出,箭头函数没有 constructor 方法,所以不能用作构造函数。 JavaScript 会通过抛出异常的方式,进行隐式地预防。

解决方法:用函数表达式代替箭头函数。

总结


回顾 MDN 给出的解释:箭头函数表达式的语法比函数表达式更短,并且没有自己的this,arguments,super或 new.target。这些函数表达式更适用于那些本来需要匿名函数的地方,并且它们不能用作构造函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值