js中关于this指向问题总结

本文深入探讨JavaScript中this关键字的指向问题,包括普通函数、定时器、箭头函数、构造函数及修改函数内部this指向的方法,如使用变量、call/apply/bind等。

记录关于this指向问题的学习

1.普通函数内部的this指向调用它的对象

    function fn() {
      console.log(this)
    };
    fn() // window
    // 直接调用,实际上是window在调用它
    function fn() {
      console.log(this);
    }
    let a = { fn };
    a.fn(); // {fn: ƒ}
    // 将fn赋给对象a的fn属性,调用a.fn,此时fn内部的this指向对象a
	function fn() {
      console.log(this);
    }
    let a = { fn };
    let b = { a };
    b.a.fn(); // {fn: ƒ}
    // 此时的this还是指向a而不是b

2.定时器中的this指向
定时器中的this是指向定义定时器时的对象,而定时器是在window中定义的,所以定时器中的this默认是指向window

    let a = {
      fn: function () {
        setTimeout(function () {
          console.log(this);
        }, 0);
      },
    };
    a.fn(); // window

3.箭头函数中的this指向
箭头函数本身并没有自己的this,箭头函数是通过读取定义该函数时的外部代码块的并绑定this,结合定时器使用的话,刚好可以达到普通函数中this的效果。

    let a = {
      fn: function () {
        setTimeout(() => {
          console.log(this);
        }, 0);
      },
    };
    a.fn(); // {fn: ƒ}

4.构造函数中的this指向
构造函数中的this指向调用它的实例,也就是new出来的新对象,实现new一共有四个步骤:

  • 1、自动创建一个空对象
  • 2、把函数内部的this指向创建的这个对象
  • 3、在函数执行完成以后自动返回创建的对象
    function Qixikuaile() {
      console.log(this);
      this.isHappy = function () {
        console.log(this);
      };
    }
    let a = new Qixikuaile();// Qixikuaile {}
    a.isHappy();// Qixikuaile {isHappy: ƒ}

当然如果不使用new的话,此时构造函数还是和普通函数一样,this指向调用它的对象

    function Qixikuaile() {
      console.log(this);
      this.isHappy = function () {
        console.log(this);
      };
    }
    Qixikuaile(); // window

同理,通过原型链添加的构造函数内的this也是如此

5.修改函数内部this指向

1).函数外部新建变量
将this赋值给该变量,在函数内部使用定义好的变量,可以解决this指向问题,如定时器中:

    function fn() {
      setTimeout(function () {
        console.log(this);
      }, 0);
    }
    let a = { fn };
    fn(); //window
    a.fn(); //window

此时fn和a.fn都指向window.

    function fn() {
      let that = this;
      setTimeout(function () {
        console.log(that);
      }, 0);
    }
    let a = { fn };
    fn(); // window
    a.fn(); // {fn: ƒ}

此时a.fn()打印出来的结果表明that指向了a,也就是调用fn的对象a.

2)Function原型链中的call和apply方法
call和apply的作用完全相同,都是旨在修改函数内部this指向,并执行该函数,不同的仅仅是传参方式。

 Function.apply(obj,args)方法能接收两个参数
 obj:这个对象将代替Function类里this对象
 args:这个是数组,它将作为参数传给Function(args-->arguments)
 Function.call(obj,param1,param2,...,paramN)
 obj:这个对象将代替Function类里this对象
 params:这个是一个参数列表
    function fn() {
      console.log(this.name);
    }
    let a = { name: "你真的快乐吗" };
    fn(); // undefined (指向window)
    fn.call(a); // "你真的快乐吗"

同理

    function fn() {
      console.log(this.name);
    }
    let a = { name: "亿点伤害" };
    fn(); // undefined (指向window)
    fn.apply(a); // "亿点伤害"

此时第一个参数a替换了fn内部的this指向,使他们指向a自己

3)Function原型链中的bind方法
bind的作用和call及apply是一样的,都是改变函数内部的this指向,
参数传递和call方法一样,不同的是bind返回的是函数本身,并不像call和apply那样会立即执行

    function fn() {
      console.log(this.name);
    }
    let a = { name: "呜呜呜" };
    fn(); // undefined (指向window)
    fn.bind(a)(); // "呜呜呜"

需要在bind后添加小括号,使函数执行

目前想到的就这些,如有不足,望指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值