一篇文章让你吃透 this 指向:面试不再慌!

192 阅读3分钟

首先,我们需要明白 this 只是函数执行上下文中的一个属性,它的值取决于函数的调用方式,是动态绑定的。

在全局作用域中的this

全局作用域中this指向全局对象

  1. Node.js 环境中 this 指向 global 对象

    1763788377699_744EC486-339A-42d3-8EBD-4B3BB9E37D4D.png

  2. 浏览器环境this 指向 window 对象

    1763788834833_B4264534-0801-47ae-9DC8-B78A6D20626B.png
  3. “伪全局” : Node.js的独立模块中 this 指向 module.exports

    • 在Node.js环境中每一个文件都是一个独立模块,在模块内部 this 不指向global对象,而是 module.exports对象
    1763789781328_37AF1DA6-ABF6-4fc6-A601-44A9C34C4BB3.png

this的绑定规则:函数中的this

函数中的this指向就较为复杂了主要分为三种绑定规则

  1. 默认绑定 :当函数被独立调用时,函数中的this指向全局对象

    • 在浏览器环境中
    1763790658302_9B4C2C20-BDFD-4ad8-92D1-FD3B313B065A.png
  2. 隐藏绑定隐式丢失

    • 隐式绑定:当函数被其它对象引用,且被该对象调用时,函数中的this会绑定到该对象上。

      1763791374295_C90ADB69-1F29-419f-B417-BDFB3504C934.png
    • 隐式丢失:类似于就近原则,当函数被多层对象调用时,函数的this指向离函数最近的对象。

      EEB78C8E-8E11-4832-9411-6A8A5BCE11EB.png
       - 图中this 指向了对象 obj 而不是 obj_1
      
  3. 显式绑定:利用call(),apply(),bind() 函数主动将函数中的this绑定到某个对象上。 在Function的原型中存在call(),apply(),bind()等方法用于显式绑定this,因此所有函数都可以直接使用这些方法

    B3DF60DD-DECC-4185-8F1A-2C0EF4A774A9.png
  • 利用call()函数 显式绑定this

    1763793533655_A8E65220-E121-4c75-A51F-D4A09BB09B4A.png
    • 且call()函数还可以帮助调用它的对象接收参数

      1763793704334_0FD59C88-6C2A-458f-8641-CDB0B3098916.png
  • apply() 作用与call相同,只是apply接收参数的方式不同,apply接收的参数是一个数组。适合多值传递。

    1763793851845_43EF233C-F352-4e53-83BA-7B3A55E2598C.png
  • 利用bind(),作用与call相同,但是会返回一个新的函数对象,并且只绑定但不触发函数

    • 只绑定不触发

      1763794003093_B9F0266D-D733-4d7d-BD36-1CC056B1EAE3.png
    • 现在我们把新的函数触发掉

      1763794123854_BA1CCB8D-F509-45a5-99D3-88D5E24E06C5.png
      - 我们发现 bind()包装后的函数同样可以帮助原函数接收参数
      

扩展

  1. 箭头函数:没有自己的this属性,如果在箭头函数中写下this关键字,此关键字代表箭头函数外层中的this。

    1763796160184_FD2F5E09-DB40-4d94-8ECA-738CB043612F.png
    - this指向全局,而不是obj对象,说明this借用的是obj对象的this
    
    • 证明:箭头函数自身内部不具备this属性
    1763796321781_FB676D19-5A07-4a28-8BF0-E6B3E297224E.png
    - 如果obj对象内部定义了一个普通的函数体,obj.fn()调用时,函数中的this指向的是obj对象
    

总结

  1. 全局作用域中,this指向该环境的全局对象或者模块(global,window,module.exprots)
  2. 函数中的this,共有三种绑定规则
    • 默认绑定,函数被独立调用,this指向全局对象
    • 隐式绑定,函数被其它对象引用时,this指向引用该函数的对象
      • 隐式丢失,多层调用函数时,this指向离该函数最近的对象
    • 显式绑定:利用Function原型中定义的函数call()、apply()、bind()等函数主动为函数中的this绑定一个对象。
  3. 箭头函数不拥有自己的this属性