ES5和ES6中的this问题及注意事项(附带少许作用域链查找知识)

本文参考以下文章:

1、深入理解ES6箭头函数的this以及各类this面试题总结

2、深入理解ES6箭头函数中的this

3、什么时候你不能使用箭头函数?

阅读本文请先阅读以上文章

要点总结:

导致不同的最本质原因是:函数表达式中有自己的this对象,而箭头函数中无自己的this对象。

函数表达式中的this:

1、this总是代表它的直接调用者, 也就是说是动态绑定的。例如 obj.func ,那么func中的this就是obj

2、在默认情况(非严格模式下,未使用 'use strict'),没找到直接调用者,则this指的是 window (约定俗成)

3、在严格模式下,没有直接调用者的函数中的this是 undefined

4、使用call,apply,bind(ES5新增)绑定的,this指的是绑定的对象

5、匿名函数,定时器中的函数,由于没有默认的宿主对象,所以默认this指向window

箭头函数中的this:

箭头函数中因为没有自己的this对象,所以在箭头函数中引用this时,会根据作用域链的寻找机制,去它的父执行上下文(注意:简单对象(非函数)是没有执行上下文的!这是作用域链的相关知识)里寻找this。

注意事项:

在需要动态上下文的场景中使用箭头函数你要格外的小心,这些场景包括:定义对象方法、定义原型方法、定义构造函数(why?this对象指向window对象了,相当于定义了全局变量)、定义事件回调函数。

经典例题:

window.val = 1;
 var obj = {
   val: 2,
   dbl: function () {
     this.val *= 2;
     val *= 2;
     console.log(val);
     console.log(this.val);
   }
 };
 // 说出下面的输出结果
 obj.dbl();//12行
 var func = obj.dbl;
 func();//14行

解析:
结果是: 2 4 8 8

12行代码调用,val变量没有指定对象前缀,默认从函数中找,找不到则从window中找全局变量,(涉及到作用域链的寻找机制:为什么不是找到obj对象中的val属性?因为按照作用域链机制,会先在自己的执行上下文中找,这个执行上下文指的是定义的dbl这个函数,如果找不到会到它的父执行上下文中找,这个父执行上下文就到了最顶层,即window对象。重中之重知识点:简单对象(非函数)是没有执行上下文的!)即 val *=2 就是 window.val *= 2,this.val默认指的是 obj.val ;因为 dbl()第一次被obj直接调用;

14行代码调用,func() 没有任何前缀,类似于全局函数,即 window.func调用,所以第二次调用的时候, this指的是window, val指的是window.val,第二次的结果受第一次的影响。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容