• 5分钟彻底搞懂this指向问题 (附练习题)


    js 中 this 到底是什么?

    当函数被调用时 ,会创建一个会话记录。记录方法 传入参数等信息,this 就是其中一个属性而已,会在函数执行时用到。

    this 绑定规则 (记住就行)

    1. 函数是否在 new 中调用(new 绑定)?如果是的话 this 绑定的是新创建的对象。
    
    2. 函数是否通过 call、apply(显式绑定)或者硬绑定调用?如果是的话,this 绑定的是指定的对象。
    
    3. 函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this 绑定的是那个上
    下文对象。(特征对象 包括普通对象 实例对象 函数对象)
    
    4. 如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到 undefined,否则绑定到全局对象。
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    特殊补充

    1.箭头函数

    
     本身是没有this 属性的,由创建时候的词法作用域决定的。不受调用对象的影响 ,受上级的词法作用域影响
     例子:
     var age = 100
     let obj = {
        name:'obj',
        age:20,
        showName:function(){
          // this 指 小p
           return ()=>{
              // 这里的this 就是小P
              console.log(this.name)
            }
        },
        showAge:()=>{
             console.log(this.age)
        }
     }
    obj.showName()()// 这时候 小P 属于上下文对象 中 this 所以就是对象本身 就是obj this.name 就是obj
    
    obj.showName.call({name:'call'})()//属于 强绑定 this 就是 {name:'call'}
    
    obj.showAge()// this 就是全局对象
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    2.函数的间接引用,调用这个函数会应用默认规定规则

    function foo() {
    console.log( this.a );
    }
    var a = 2;
    var o = { a: 3, foo: foo };
    var p = { a: 4 };
    o.foo(); // 3
    (p.foo = o.foo)(); // 2
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    练习

    var name = 'window'
    
    var person1 = {
      name: 'person1',
      foo1: function () {
        console.log(this.name)
      },
      foo2: () => console.log(this.name),
      foo3: function () {
        // 这里this 是 小foo3
        return ()=> {
          console.log(this.name)
        }
      },
      foo4: function () {
        return function() {
          console.log(this.name)
        }
      }
    }
    
    var person2 = { name: 'person2' }
    
    
    // 开始题目:
    person1.foo1();//上下文对象 person1
    person1.foo1.call(person2);//强关联对象 person2
    
    person1.foo2();//箭头函数的上级词法作用域绑定 this 满足4 默认规则 window
    person1.foo2.call(person2);//call 方法没有改变 箭头函数的上级词法作用域(全局作用域)所以还是 window 
    
    person1.foo3()();// 箭头函数上级词法作用域 就是 小foo3(上下文对象) 所以this就是 person1 
    person1.foo3.call(person2)();//这里强绑定改变了 小foo3 的指向 (person2)所以this 就是 person2
    person1.foo3().call(person2);// 这里同上 没有改变 箭头函数的上级词法作用域 所以 this 还是 person1
    
    person1.foo4()();//属于规则4 window
    person1.foo4.call(person2)();//属于规则4 window 
    person1.foo4().call(person2);// 属于规则2 强绑定 person2
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
  • 相关阅读:
    用 Python 自动创建 Markdown 表格 - 每天5分钟玩转 GPT 编程系列(4)
    带你入门HTML+CSS网页设计,编写网页代码的思路
    性能测试岗位能力模型
    C#描述-计算机视觉OpenCV(5):直方图算法
    Zookeeper简述
    16. 机器学习——决策树
    如何用Postman做接口自动化测试?一文5个步骤带你成功实现!
    sql语句查询某字段中有汉字的数据
    刷题总结碎碎念
    git学习笔记
  • 原文地址:https://blog.csdn.net/weixin_45485922/article/details/127649137