箭头函数
参考链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions
本系列是在平时阅读、学习、实际项目中有关于es6中的新特性、用发的简单总结,目的是记录以备日后温习;本系列预计包含let/const、箭头函数、解构、常用新增方法、Symbol、Set&Map、Proxy、reflect、Class、Module、Iterator、Promise、Generator、async/await。。。
箭头函数顾名思义就是带箭头的函数,^-^,其实想表达的是箭头函数本质还是函数,那箭头函数和es5的函数有什么区别呢?
- 不绑定this
var obj = { age: 1, say: function() { setTimeout(function() { console.log(this, this.age); // window undefined }, 0); }, }
</span><span style="color: #0000ff;">var</span> obj1 =<span style="color: #000000;"> { age: </span>1<span style="color: #000000;">, say: </span><span style="color: #0000ff;">function</span><span style="color: #000000;">() { setTimeout(() </span>=><span style="color: #000000;"> { console.log(</span><span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">this</span>.age); <span style="color: #008000;">//</span><span style="color: #008000;"> obj1 1</span> }, 0<span style="color: #000000;">); } };</span></pre>
这里可以看出箭头函数中访问的this实际上是其父级作用域中的this,箭头函数本身的this是不存在的,这样就相当于箭头函数的this是在声明的时候就确定了(因为相当于作用域嘛),这个特性是很有用的
var handler = { id: '111', doSomething: function(e) { console.log(e); }, init: function() { document.addEventListener('click', (event) => { // 这里绑定事件,函数this就可以访问到handler的方法doSomething this.doSomething(event); }, false); } }
handler.init();</span></pre>
- 不可以作为构造函数来使用
var Person = (name) => { // Uncaught TypeError: Person is not a constructor this.name = name; }
</span><span style="color: #0000ff;">var</span> person = <span style="color: #0000ff;">new</span> Person('Jack');</pre>
这个特性很容易测试,如果上一条明白的话也很容易理解: 箭头函数压根就没有this,当然不能作为构造函数(如果明白构造函数new的过程的话,插一句: new的过程其实就是创建一个对象,将this指向该对象,然后执行代码初始化这个对象,最后返回)
- 不绑定arguments(如果有要使用arguments的时候可以使用rest参数代替)
var foo = (val) => { console.log(arguments); // Uncaught ReferenceError: arguments is not defined }; foo();
这个特性也很好测试,但是实在要使用arguments对象要怎么办呢?我们可以使用es6的另一个新特性rest参数,完美替代
var foo = (...args) => { console.log(args); // [1, 2, 3] }; foo(1, 2, 3);
- 不可以使用yield命令,因此箭头函数不能用作Generator函数(这个后面总结到generator函数时再做解释)
箭头函数不适用的场景(或者不建议使用的场景)
这里说的不适用有些是压根不能用,有些是如果使用了箭头函数可能会产生意想不到的结果
- 作为对象的属性
var obj = { a: () => { console.log(this); // window } };
作为对象的属性时,this的指向则不再是对象本身了,这就造成了意想不到的结果
- 构造函数(前文已经说过)
- 作为原型方法
function Person(name) { this.name = name; }
Person.prototype.say </span>= <span style="color: #0000ff;">function</span><span style="color: #000000;">() { console.log(</span><span style="color: #0000ff;">this</span>); <span style="color: #008000;">//</span><span style="color: #008000;"> 指向实例</span>
};
Person.prototype.bark </span>= () =><span style="color: #000000;"> { console.log(</span><span style="color: #0000ff;">this</span>); <span style="color: #008000;">//</span><span style="color: #008000;"> window</span>
};
</span><span style="color: #0000ff;">var</span> pe = <span style="color: #0000ff;">new</span> Person('Jack'<span style="color: #000000;">); pe.say(); </span><span style="color: #008000;">//</span><span style="color: #008000;"> {name: 'Jack'}</span> pe.bark(); <span style="color: #008000;">//</span><span style="color: #008000;"> window</span></pre>
从例子中我们看到了,箭头函数作为原型方法时,this指向出乎了我们的意料
- 需要动态this的时候(这个地方需要自己进行判断),这里只举个例子便于理解
document.addEventListener('click', () => { console.log(this); // window }, false);
document.addEventListener(</span>'click', <span style="color: #0000ff;">function</span><span style="color: #000000;">() { console.log(</span><span style="color: #0000ff;">this</span>); <span style="color: #008000;">//</span><span style="color: #008000;"> #document对象</span> }, <span style="color: #0000ff;">false</span><span style="color: #000000;">);
// 一般情况,我们绑定事件处理函数时希望函数内部的this指向绑定的Dom对象,但是如果使用了箭头函数,则this则会出乎我们的意料