ES6 容许使用“箭头”(=>)定义函数javascript
<p id="test1">测试</p> var p1 = document.getElementById('test1'); p1.addEventListener('click', () => { p1.style.color = "red"; }, false);
在es5中至关于java
var p1 = document.getElementById('test1'); p1.addEventListener('click', function () { //直接经过dom的方法改变颜色 this.style.color = "red"; },false);
可是咱们思考一个问题——当咱们把第一段代码中的p1换成this时
this会指向哪里app
p1.addEventListener('click', () => { this.style.color = "red";// 'color' is not undefined }, false);
这时咱们就会想this为何没有做用,而在es5中this是指向了p1dom
函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
this对象的指向是可变的,可是在箭头函数中,它是固定的。函数
function foo() { setTimeout(() => { console.log('id:', this.id); }, 100); } var id = 21; foo.call({ id: 42 }); // id: 42
上面代码中,setTimeout的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它的真正执行要等到100毫秒后。若是是普通函数,执行时this应该指向全局对象window,这时应该输出21。可是,箭头函数致使this老是指向函数定义生效时所在的对象(本例是{id: 42}),因此输出的是42学习
this指向的固定化,并非由于箭头函数内部有绑定this的机制,实际缘由是箭头函数根本没有本身的this,致使内部的this就是外层代码块的this。正是由于它没有this,因此也就不能用做构造函数。测试
// ES6 function foo() { setTimeout(() => { console.log('id:', this.id); }, 100); } // ES5 function foo() { var _this = this; setTimeout(function () { console.log('id:', _this.id); }, 100); }
上面代码中,转换后的es5清楚地说明了,箭头函数里面根本没有本身的this,而是引用外层的this。this
因为箭头函数没有本身的this,因此固然也就不能用call()、apply()、bind()这些方法去改变this的指向。es5
(function() { return [ (() => this.x).bind({ x: 'inner' })() ]; }).call({ x: 'outer' }); // ['outer']
一样的因为箭头函数没有本身的this 因此bind传统的显性绑定无效 内部的this指向外部this
在javascript的学习中, this的指向问题一直是个难点,特别是在对象方法中使用this时,必须更加当心。由此箭头函数在很大程度上减小了咱们的困扰。code
话又说回来,当咱们使用箭头函数时不使用常规的四种this绑定,又该怎么决定this的指向问题呢?
箭头函数是根据外层(函数或者全局)做用域来决定this
让咱们看看箭头函数的此法做用域:
function foo() { //返回箭头函数 return(a) => { //this 继承自foo() console.log(this.a); }; } var obj1 = { a:2 }; var obj2 ={ a:3 }; var bar = foo.call(obj1); bar.call(obj2); //是2, 不是3!!!
foo()内部建立的箭头函数会捕获调用时foo()的this。因为foo()的this绑定到了obj1,因此bar(引用箭头函数)的this也会绑定到obj1,上文说过箭头函数this对象的指向是固定的因此后面的call修改不了绑定,即便是new也不行。
箭头函数能够像bind()同样确保函数的this被绑定到指定对象上,此外, 其重要性还体如今它更常见的词法做用域取代了传统的this的机制。实际上, 在ES6以前咱们就已经在使用一种集合和箭头函数彻底同样的模式了。
function foo() { var self = this; setTimeout(function() { console.log(self.a) },100) } var obj = { a:2 }; foo.call(obj);
和箭头函数同样self = this 看起来均可以取代bind(), 可是从本质上来看,它们是想代替this这个机制。
若是常常编写this风格的代码,又喜欢用箭头函数或者self= this的方法来否认this机制。
那么或许你应当: