首先复习下普通函数里的this指向:函数
1 function test(){ 2 console.log(this) 3 } 4 test()
你会秒杀的毫无疑问的回答:window,针对普通函数:谁调用了函数 函数里的this就指向谁,test()等价于window.test(),因此是windowthis
1 var name="outername" 2 var o={ 3 name:"innername", 4 getname:function(){ 5 console.log(this.name) 6 } 7 } 8 o.getname()
这个是普通函数,谁调用了函数 函数里的this就指向谁,o.getname(),调用这个getname函数的是o这个对象,这个o对象下面有name:"innername",因此打印出的是 "innername"spa
怎么还不见ES6里的箭头函数呢?别急立刻登场:看我变身code
1 var name="outername" 2 var o={ 3 name:"innername", 4 getname:()=>{ 5 console.log(this.name) 6 } 7 } 8 o.getname()
哇,箭头函数出来了,o.getname()执行后,由于箭头函数坐镇,我不敢轻易的说,由于调用getname()的是o对象,因此this指向o对象,哦NO,但是人家不是普通函数,人家是箭头函数,哪就猜相反的那个var name="outername",它会打印外面的那个name("outername"),恭喜你,答对了,缘由下面会讲解。对象
1 var name="outername" 2 var o={ 3 name:"innername", 4 getname:function(){ 5 return ()=>this.name 6 7 } 8 } 9 console.log(o.getname()())
箭头函数继续出现,那么这个会打印出什么呢?不想猜的我直接敲出代码打印出来答案:"innername",为何?箭头函数的this对象:就是定义时所在的对象,而不是使用时所在的对象,也就是根据外层(函数或者全局)做用域来决定this,再最后个例子一并总结.blog
1 var name="outername" 2 var o={ 3 name:"innername", 4 getname:function(){ 5 setTimeout(()=>console.log(this.name),1000) 6 7 } 8 } 9 o.getname()
待我先总结完后本身能够先去猜下没有给出答案的答案.作用域
总结:get
普通函数this指向:谁调用了函数 函数里的this就指向谁io
箭头函数的this指向:就是定义时所在的对象,而不是使用时所在的对象,也就是根据外层(函数或者全局)做用域来决定thisconsole
调用的函数类型:
①箭头函数:this指向window
②普通函数:this指向调用这个普通函数的对象,可能这个普通函数里有箭头函数,否管它,即便这个普通函数里有箭头函数,这个箭头函数的this依旧是调用这个普通函数的对象
小结以上调用的函数是普通函数缺内嵌箭头函数的例子:
1 var name="outername" 2 var o={ 3 name:"innername", 4 getname:function(){ 5 return ()=>this.name 6 7 } 8 } 9 console.log(o.getname()())
1 var name="outername" 2 var o={ 3 name:"innername", 4 getname:function(){ 5 setTimeout(()=>console.log(this.name),1000) 6 7 } 8 } 9 o.getname()
this
对象的指向是可变的,可是在箭头函数中,它是固定的。
1 function foo() { 2 setTimeout(() => { 3 console.log('id:', this.id); 4 }, 100); 5 } 6 7 var id = 21; 8 9 foo.call({ id: 42 }); 10 // id: 42
上面代码中,setTimeout
的参数是一个箭头函数,这个箭头函数的定义生效是在foo
函数生成时,而它的真正执行要等到 100 毫秒后。若是是普通函数,执行时this
应该指向全局对象window
,这时应该输出21
。可是,箭头函数致使this
老是指向函数定义生效时所在的对象(本例是{id: 42}
),因此输出的是42
。
但愿此篇认清ES6箭头函数里的this指向,对你有用。