一篇文章让你搞懂this

前言:this到底是什么

当一个函数被调用时,会产生一个活动记录(也称之为执行上下文),这个记录包含调用栈(函数在哪里被调用),函数调用方式,调用传入参数等信息,this就是活动记录的一个属性。this实际上是函数调用时发生的绑定,它的指向取决于函数在哪里被调用。

一.this调用位置

    查找方法:在工具中给foo()函数的第一行代码设置断点,或者直接在第一行代码之前插入一条debugger;语句,运行代码时。调试器会在那个位置暂停,同时显示当前位置的函数调用列表,这就是你的调用栈,因此如果分析this绑定,先查找调用栈,找到栈中第二个元素就是真正的调用位置。

 

image

 

二.绑定规则

默认绑定

    1.使用非严格模式 ,默认绑定才能绑定到全局对象

image

2.如果使用严格模式,则不能将全局对象用于默认绑定,this会绑定到undefined

截屏2020-08-16上午6.17.44.png

隐式绑定

在一个对象内部包含一个指向函数的属性,通过这个属性间接调用这个函数,从而使this间接(隐式)绑定到这个对象上


  • 当函数引用有上下文对象时,隐式绑定会将this绑定到这个上下文对象上
  • 对象属性引用链中只有上一层或者说最后一层在调用位置起作用

截屏2020-08-16上午6.41.16.png

  • 隐式丢失

       被隐式绑定的函数会丢失绑定对象,也就是它会应用默认绑定,从而把this绑定到全局对象或者undefined上,取决于是否是严格模式

截屏2020-08-16上午6.49.22.png

 

显式绑定

  • 使用call()或apply()方法
  • 上述两种方法,第一个参数是对象,给this准备的,接着在调用函数时将其绑定到this

     1.使用硬绑定可以解决丢失绑定的问题,硬绑定无法修改this值

截屏2020-08-17上午11.24.55.png

     补充: 使用bind()返回一个新编码的新函数,它会把你指定参数设置为this的上下文并调用原函数。

   2.API调用“上下文”,其作用和bind()一样,确保回调函数使用确定this

截屏2020-08-17上午11.39.51.png

new绑定

构造函数是使用new操作符时调用的函数

  一.使用new来调用函数过程

  •     创建(或构造)一个全新的对象
  •     这个对象会执行[[Prototype]]连接
  •     这个新对象会绑定到函数调用的this
  •     如果函数没有返回对象,那么new表达式中的函数调用会自动返回这个对象

使用new调用foo(...)时,我们会创建一个新对象并把它绑定到foo(...)调用中的this

截屏2020-08-17上午11.54.11.png

 

三.绑定优先级

总结:new绑定>显式绑定>隐式绑定>默认绑定

截屏2020-08-17下午2.51.44.png

ps:bind()功能之一就是可以把除了第一个参数(第一个参数用于this绑定)之外其他参数传给下层函数(该技术称为this)

截屏2020-08-17下午3.01.05.png

四.判断this

按照以下规则判断

  • 函数是否在new中调用=>this绑定的就是新创建对象

    var bar=new foo()    //this绑定bar

  • 函数是否通过call,apply(显式绑定)或硬绑定调用=>this绑定的就是指定的对象

    var bar =foo.call(obj1)   //this绑定obj1

  • 函数是否在某个上下文中调用(隐式绑定)=>this绑定上下文对象

    var bar=obj1.foo()     //this绑定obj1,谁调用绑定谁

  • 如果都不是=>使用默认绑定,在严格模式下就绑定到undefined,否则就绑定到全局对象

     var bar=foo()

 

五.绑定例外

    被忽略的this

      1.如果把null或undefined作为this的绑定对象传入call、apply或者bind,这些值会在调用时被忽略,实际应用默认绑定规则

截屏2020-08-17下午3.28.05.png截屏2020-08-17下午3.28.05.png

      由于当某些函数确实用了this,但是默认绑定规则把this绑定到全局对象,会导致不可预见结果,必须采用一种更安全的this

      更安全的this

      2.传入一个特殊对象,把this绑定到这个特殊对象上不会对程序产生任何副作用,创建一个DMZ对象,它是一个空的非委托对象
      截屏2020-08-17下午3.38.28.png

      使用ø不仅会让函数变得更安全,还能提高代码可读性,因为ø表示"我希望this是空"

  间接引用

   可能有意或无意创建一个函数的"间接引用",在这个情况下函数调用会应用默认绑定

截屏2020-08-17下午3.47.01.png

软绑定

六.this词法

箭头函数不使用this的四条绑定规则,而是根据外层(函数或全局)作用域来决定this

箭头函数会继承外层函数调用的this绑定(无论this绑定到什么)

截屏2020-08-17下午3.57.22.png

 

 
 
原文地址:https://www.cnblogs.com/mernva/p/13649526.html