一文搞懂this的指向问题

引言:

关于 this 有一个非常重要的思想要知道,this不是写在哪里就被绑定在哪里,而是代码运行的时候才被绑定。也就是说如果一个函数中存在this,那么this到底指什么取决于这个函数以什么样的方式被调用下面常见的几个场景:

一、全局环境

在全局环境中,this 指向全局对象,在浏览器中是window,node环境中是 global

二、普通函数调用 

对于直接调用普通函数(非箭头函数)来说,不管函数在什么地方被调用,this 一定是全局对象

function f1() {
    console.log(this.name);
}

function f2() {
    f1();
}
var name = '小红';
f1(); // 小红
f2(); // 小红

三、对象方法调用

当函数被作为对象方法调用时,谁调用了函数,谁就是 this

const obj = {
    name: '小明',
    f1: function () {
        console.log(this.name);
    },
    f2() {
        console.log(this.name);
    }
}
obj.f1(); // 小明
obj.f2(); // 小明

四、构造函数

在构造函数中,this 指向 new 创建的对象

function F1() {
    this.name = '小红';
}

const f1 = new F1();
f1.name; // '小红'

五、箭头函数函数

箭头函数中没有this,所以箭头函数中的 this 与包裹箭头函数的第一个普通函数的 this保持一致

function a() {
  return () => {
    return () => {
      console.log(this)
    }
  }
}
console.log(a()()()) // window

因为包裹箭头函数的第一个普通函数是 a,所以此时的 this 是 window。另外对箭头函数使用 bind 这类函数是无效的。

六、call/apply/bind调用

bind、apply、call都是用来改变函数的this对象指向的,第一个参数都是this要指向的对象

var xw = {
  name: "小王",
  say: function() {
    console.log(this.name);
  }
};
var xh = {
  name: "小红"
};
xw.say();          // 小王
xw.say.call(xh);   // 小红
xw.say.apply(xh);  // 小红
xw.say.bind(xh)(); // 小红

可以看出,三种方法都能改变this的指向,用xw的say方法来显示xh的数据,但是有什么区别呢?

  • 直接写xw.say.bind(xh)是不会输出结果的,call和apply都是对函数的直接调用,而bind方法返回的仍然是一个函数,因此需要用()来进行调用才行;
  • call可以传入多个参数;
  • apply只能传入两个参数,所以其第二个参数往往是作为数组形式传入

优先级:

当多个规则同时出现的时候,就会根据优先级的来决定 this 的最终指向,优先级如下:

new > bind,apply,call > 对象方法 > 普通方法

箭头函数的 this 一旦被绑定,就不会再被任何方式所改变。

总结:

  1. 对于直接调用普通函数this 一定是全局对象
  2. 对于 obj.foo() 来说,我们只需要记住,谁调用了函数,谁就是 this,所以在这个场景下 foo 函数中的 this 就是 obj 对象
  3. 在构造函数中,this 指向 new 创建的对象,this不会被任何方式改变
  4. 箭头函数中没有this,所以箭头函数中的 this 只取决包裹箭头函数的第一个普通函数的 this
  5. 使用call/apply/bind方法时,this指向第一个参数 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值