阅读 82

一句话概括this指向问题(谈谈对this指向的理解)

一句话概括

js this指向问题是一个痛点,但理解也不难,核心思想:
this指向并不取决于定义,而是取决于调用

解释

在this定义的地方,沿着作用域向上找,找到最近的一个function(箭头函数除开,因为es6的箭头函数不带有this),看这个function最终是怎样执行的,this的指向就取决于所属function的调用方式,而不是定义。

function的调用一般分以下5种情况

  1. 作为函数调用,即:fun()
    this指向全局对象,注意严格模式问题(严格模式全局的this指向的是undefined)
    在浏览器里全局对象是window,在node里全局对象是Object [global]

  2. 作为方法调用,即:obj.fun() / obj.bar.fun() / obj['fun']
    this指向最终调用这个方法的对象

  3. 作为构造函数调用,即:new Foo()
    this指向一个新对象foo {}

    function foo(){   console.log(this) // => foo {} } new foo() 复制代码

  4. 特殊调用,即:fun.call() / fun.apply() / fun.bind()
    this指向绑定的第一个参数成员,如果没有传入参数,则指向全局对象

  5. 找不到所属的function,就是全局对象

掌握这5点总结,能覆盖所有的this指向问题,下面一些测试,你能答对吗?

测试

1、

var length = 10 function fn() {   console.log(this.length) } const obj = {   length: 5,   method(fn) {     fn()     arguments[0]()   } } obj.method(fn, 1, 2) 复制代码

浏览器里执行打印10 3
第一个10,this命中情况1:作为函数调用,this指向全局,所以访问挂载到window上的length为10
第二个3,this命中情况2:作为方法调用,this指向arguments对象{ '0': [Function: fn], '1': 1, '2': 2 },所以length打印3

2、

const obj1 = {   foo(){     return () => {       console.log(this)     }   } } obj1.foo()() const obj2 = {   func : () => {     console.log(this)   } } obj2.func() 复制代码

第一个打印obj1对象,this命中情况2:作为方法调用,沿this往上找跳过箭头函数找到function foo,foo由obj1调用,则指向obj1
第二个浏览器打印window,this命中情况5:向上找不到function,就指向全局

3、

class Person{   say = () => {     console.log(this)   } } const p = new Person() p.say() 复制代码

打印实例Person,this命中情况3:作为构造函数调用,class是Function的语法糖,实质是function,this指向实例p


作者:熊猫爱吃笋
链接:https://juejin.cn/post/7029213661692428295


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐