Open phenomLi opened 6 years ago
箭头函数() => ()是ECMAScript2015中代替function的一个语法糖,他增强了JS中Functional programming的能力。箭头函数与传统的functuon(){}声明并没有什么区别,但是在表现上,还是有一点微小区别的,而且这微小区别如果处理不好就会出现大bug。 先看看官方对箭头函数与function的区别的定义:
() => ()
function
functuon(){}
1、对 this 的关联。函数内置 this 的值,取决于箭头函数在哪儿定义,而非箭头函数执行的上下文环境。 2 、new 不可用。箭头函数不能使用 new 关键字来实例化对象,不然会报错。 3、this 不可变。函数内置 this 不可变,在函数体内整个执行环境中为常量。 4、没有arguments对象。更不能通过arguments对象访问传入参数。只能使用显式命名或其他ES6新特性来完成。
第四点不重要,重要的是前三点,简单来说,就是箭头函数和function对内部的this的处理是不一样的。function内部的this由function决定,而箭头函数的this则由上下文决定。下面来看一个小例子:
const obj = { a: function() { console.log(this); }, b: () => { console.log(this); } }; obj.a(); //输出obj obj.b(); //输出window
可以看到在箭头函数中,this指针指向的是全局变量window。 为什么会这样呢,其实上面js字面量的写法就等同于下面这种:
const obj = {}; obj.a = function() { console.log(this); }; obj.b = () => { console.log(this); };
这时外层上下文并不是obj而是window,所以箭头函数里面this就指向了window。
有时候这种特性会很方便,比如,我们要在setTimeout函数里面获取当前对象,如果这样写:
setTimeout
const obj = { fn: function() { setTimeout(function() { console.log(this); //window }, 0); } };
会发现打印出来的值是window对象而不是obj,因为setTimeout的真正写法是window.setTimeout此时setTimeout里面的上下文是window,打印出来的自然是window。 但是如果想要在setTimeout里面获得obj该怎么办呢,一种老的hack写法是这样:
window.setTimeout
const obj = { fn: function() { const _this = this; //保存当前上下文 setTimeout(function() { console.log(_this); }, 0); } };
老的写法是把当前this保存在一个变量里,但是这种写法毕竟是一种hack。现如今有了箭头函数,我们可以这样做:
const obj = { fn: function() { setTimeout(() => { //使用箭头函数 console.log(this); //obj }, 0); } };
因为箭头函数中的this根据的是外层上下文,而在setTimeout函数中内层是window,外层是obj,所以可以轻松拿到正确的值。 之前在写react的过程中,就遇到了箭头函数的一些坑,如在React.createClass方法中,最好不要用箭头函数来声明方法:
React.createClass
const trank = React.createClass({ handler: () => { console.log('now the pointer "this" is ' + this + '.'); //点击div,打印出的this是window this.setState(); //同时setState方法也会无效 }, render: function() { return React.createElement('div', {onClick: this.handler}, 'hello'); } });
至于具体原因,上面也解释得很清楚了,就是上下文得问题,至于解决方法,目前只有两个:
箭头函数
() => ()
是ECMAScript2015中代替function
的一个语法糖,他增强了JS中Functional programming的能力。箭头函数与传统的functuon(){}
声明并没有什么区别,但是在表现上,还是有一点微小区别的,而且这微小区别如果处理不好就会出现大bug。先看看官方对箭头函数与function的区别的定义:
第四点不重要,重要的是前三点,简单来说,就是箭头函数和function对内部的this的处理是不一样的。function内部的this由function决定,而箭头函数的this则由上下文决定。下面来看一个小例子:
可以看到在箭头函数中,this指针指向的是全局变量window。 为什么会这样呢,其实上面js字面量的写法就等同于下面这种:
这时外层上下文并不是obj而是window,所以箭头函数里面this就指向了window。
有时候这种特性会很方便,比如,我们要在
setTimeout
函数里面获取当前对象,如果这样写:会发现打印出来的值是window对象而不是obj,因为
setTimeout
的真正写法是window.setTimeout
此时setTimeout
里面的上下文是window,打印出来的自然是window。 但是如果想要在setTimeout
里面获得obj该怎么办呢,一种老的hack写法是这样:老的写法是把当前this保存在一个变量里,但是这种写法毕竟是一种hack。现如今有了箭头函数,我们可以这样做:
因为箭头函数中的this根据的是外层上下文,而在
setTimeout
函数中内层是window,外层是obj,所以可以轻松拿到正确的值。之前在写react的过程中,就遇到了箭头函数的一些坑,如在
React.createClass
方法中,最好不要用箭头函数来声明方法:至于具体原因,上面也解释得很清楚了,就是上下文得问题,至于解决方法,目前只有两个: