彻底搞懂JS中this绑定规则

JS中this指向绑定规则可以分为以下几种:

  1. 默认绑定
  2. 隐式绑定
  3. 显示绑定
  4. new绑定

1.默认绑定

当无法应用前面说的其它三种规则的时候,就会应用默认绑定,此时的this会绑定全局对象(注:在严格模式下this无法绑定全局对象而是绑定到underfind)

    var a = 1

    function fn1() {
      console.log(this)
      console.log(this.a)
    }


    function fn2() {
      "use strict"
      console.log(this)
      console.log(this.a)
    }

    fn1()
    fn2()
    /*打印结果
      Window
      1
      undefined
      Cannot read property 'a' of undefined
    */

2.隐式绑定

当调用的位置含有执行上下文时,this会绑定这个上下文对象

function fn() {
      console.log(this)    
      console.log(this.a)
    }
    var obj = {
      a: 1,
      fn: fn
    }

    obj.fn()

    /*打印结果
    {a: 1, fn: ƒ}   //obj这个对象
    1
    */

此外对象属性引用链中只有最顶层或者说最后一层会影响调用位置

function fn() {
      console.log(this)
      console.log(this.a)
    }

    var obj2 = {
      a: 2,
      fn: fn
    }

    var obj1 = {
      a: 1,
      obj2: obj2,
    }
    
    obj1.obj2.fn()

    /*打印结果
    {a: 2, fn: ƒ}   //obj2这个对象
    2
    */

隐式绑定有时也会带来隐式丢失的问题,最常见的一种就是被隐式绑定的函数丢失绑定对象,换句话说就是采用默认绑定,把this绑定到全局对象上

 function fn() {
      console.log(this)
      console.log(this.a)
    }

    var obj = {
      a: 1,
      fn: fn
    }

    var a = 'global'

    var b = obj.fn
    
    b()


    /*打印结果
    Window   
    global
    
    虽然b是obj.fn的一个引用,但是b()实际是调用了fn本身,所以此时的b函数是一个没有修饰的函数,即
    采用了默认绑定
    */

此外参数的传递其实也是一种隐式的赋值,下面例子的结果与上述例子的结果是一样的

function fn() {
      console.log(this)
      console.log(this.a)
    }

    function Fn(f) {
      f()   //这里的f其实也是就是函数fn的一个引用
    }

    var obj = {
      a: 1,
      fn: fn
    }

    var a = 'global'

    Fn(obj.fn)

    /*打印结果
    Window   
    global
    */

3.显式绑定

通过apply、call、bind方法来指定this绑定的对象(apply、call、bind的用法自行了解)

 function fn() {
      console.log(this)
      console.log(this.a)
    }

    var obj = {
      a: 1,

    }

    fn.call(obj)

    /*打印结果
    {a: 1}    //obj这个对象
    1
    */

其次显示绑定可以通过硬绑定这种变种的方式来解决隐式绑定丢失的问题

 function fn() {
      console.log(this)
      console.log(this.a)
    }

    var obj = {
      a: 1,

    }
    var b = function () {
      fn.call(obj)
    }

    b()

    b.call(window)

    /*打印结果
    {a: 1}    //obj这个对象
    1

    {a: 1}    //obj这个对象
    1

    首先我们创建了一个b函数并在内部强制将fn的this绑定到obj对象上,所以后面无论如何调用fn函数,
    它的this都会绑定到obj上,根据打印结果可知,硬绑定后在对其this修改是无效的
    */

4.new绑定

JS中使用new来调用函数时,会进行以下操作:

1.创建一个空对象。(var obj = new Object())
2.将空对象的原型赋值给构造函数的原型。(Person.prototype = obj.proto)
3.执行构造函数的代码,为空对象添加属性(Person.call(obj)),也可以理解为将构造函数内部的this指针指向新建的空对象。
4.如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象。

 function fn(a) {
      this.a = a
    }

    var b = new fn(1)

    console.log(b.a)  // 1
   /*
   使用 new 来调用 fno(..) 时,我们会构造一个新对象并把它绑定到 foo(..) 调用中的 this上,
   具体原因看上面new的过程做了什么
   */

总结(根据你不知道的js中的总结)

1.由 new 调用?绑定到新创建的对象
2.由 call 或者 apply(或者 bind )调用?绑定到指定对象
3.由上下文对象调用?绑定到那个上下文对象
4.默认:在严格模式下绑定到 undefined,否则绑定到全局对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值