在看阮一峰大佬的ES6时,看到一个关于箭头函数和this的例子
1 2 3 4 5 6 7 8 9 10
| function foo() { setTimeout(() => { console.log('id:', this.id); }, 100); }
var id = 21;
foo.call({ id: 42 }); // id: 42
|
输出结果竟然是42,我一直以为箭头函数的this从函数定义时就已经固定不变了,es6的教程也看过几遍,还是看书不仔细漏过了这个问题
在疑惑后也思考研究了一下,结合搜索到的例子,得出一下结论:
首先不使用箭头函数
1 2 3 4 5 6 7 8 9 10
| function foo() { console.log('this.id:',this.id); // this.id: 42 setTimeout( function () { console.log('this.id:',this.id); // this.id: 21 },100); }
var id = 21;
foo.call({ id: 42 });
|
此时结果都是可以预期的,第一行输出42,是因为call函数改变了foo的指针执行,指向为{id: 42}
第二行输出21,是因为setTimeout是挂载在window下面的。setTimeout实际上又改变了this的指针指向,将this又指向了window。因此输出21。
将函数改为箭头函数
1 2 3 4 5 6 7 8 9 10
| function foo() { console.log('this.id:',this.id); // this.id: 42 setTimeout( () => { console.log('this.id:',this.id); // this.id: 42 },100); }
var id = 21;
foo.call({ id: 42 });
|
此时第一行依旧输出42,这一点是肯定的
分析第二行,箭头函数导致this总是指向函数(箭头函数)定义生效时所在的对象,这句话换个方式理解比较容易理解和记忆,即箭头函数的this指向和将箭头函数的内容拿到函数外层的this指向是一致的
结合上面的例子就是 第二行的this应该和第一行的this是一致的
看到闭包以后,我觉得箭头函数既然没有自己的this,是不是相当于普通函数获取上一级的变量一样。。。?
再看一下这个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| var myObj = { name : "myObj", showThis: function(){ console.log(this); return () => { console.log(this.name); } } } var obj = { name: "obj" }
var fnc1 = myObj.showThis()
fnc1.call(obj) fnc1()
var fnc2 = myObj.showThis.call(obj)
fnc2()
|
可以看到 call apply 和bind 也无法改变箭头函数的this,始终取决于上层上下文的this