this绑定

this的绑定规则有几种?

  • 默认绑定
    • 当函数独立调用时

    • this 绑定到全局对象

      • 在浏览器环境中为 window,Node.js 环境中为 global
      • 在严格模式,则默认绑定为 undefined。
    • 案例代码

      function myFunction() {
        console.log(this);
      }
      myFunction(); // this 指向 window(浏览器中)或 global(Node.js 环境中)
      
      
  • 隐式绑定
    • 当函数作为对象的方法调用时,this 绑定到该对象。

    • 案例代码

      const myObject = {
        name: 'Alice',
        sayName() {
          console.log(this.name);
        }
      };
      myObject.sayName(); // this 指向 myObject,输出 "Alice"
      
  • 显式绑定
    • 明确this指向的对象,第一个参数相同并要求传一个对象。

    • apply/call

    • bind

    • 案例代码

function sayHello() {
  console.log(`Hello, ${this.name}!`);
}
const person = { name: 'Alice' };
sayHello.call(person); // this 指向 person,输出 "Hello, Alice!"
  • new绑定:
    • 当构造函数被 new 关键字调用时,this 绑定到新创建的对象实例

      • 创建一个全新对象

      • 新对象被执行prototype链接

      • 新对象绑定到函数调用的this

      • 如果函数没有返回其他对象,表达式会返回这个对象

    • 案例代码

      function Person(name) {
        this.name = name;
      }
      const alice = new Person('Alice');
      console.log(alice.name); // 输出 "Alice"
      
  • 箭头函数绑定
    • 箭头函数没有自己的 this 值
    • 箭头函数中的 this 值指向最近的非箭头函数的 this 值(来自于函数作用域链)
      • 如果没有这样的函数的情况下指向全局对象

this绑定优先级

  • 默认绑定<隐式绑定<显示绑定<new绑定
    • new绑定不可与call/apply一起使用
    • new可以和bind一起使用,new绑定优先级更高

绑定之外的情况

  • 在显示绑定中,我们传入一个null或者undefined
    • 那么这个显示绑定会被忽略,使用默认规则
function foo(){
    console.log(this);
}
var obj = {
    name:"why"
}
foo.call(obj) //obj对象
foo.call(null) //window
foo.call(undefined) //window

var bar = foo.bind(null);
bar()

  • 创建一个函数的间接引用,这种情况使用默认绑定规则
    • 赋值(obj2.foo = obj1.foo)的结果是foo函数;

    • foo函数被直接调用,那么是默认绑定;

       function foo() {
            console.log(this);
        }
        var obj1 = {
            name: "obj1",
            bar: foo
        }
        var obj2 = {
            name: "obj2"
        }
      
        obj1.bar(); //obj1对象
        (obj2.bar = obj1.bar)() //window
      

如何使用call()和apply()方法改变this的值?

  • call()和apply()的区别

    • call()方法接受一个参数列表
    • apply()方法接受一个数组参数
    function foo(){}
    
    foo.call(this,1,2,3)
    foo.apply(this,[1,2,3])
    const foo1 = foo.bind(this,1,2)
    foo1(3)
    

如何使用bind()方法改变this的值?

  • bind() 方法创建一个新的函数

    • 该函数与原始函数相同
    • 但 this 值被绑定到指定的对象。
  • bind() 方法接受一个参数,即要绑定到函数 this 的对象。

    let obj1 = { name: "Bob" };
    function sayHello() {
      console.log(`Hello, my name is ${this.name}.`);
    }
    let sayHelloToBob = sayHello.bind(obj1);
    sayHelloToBob(); // 输出 "Hello, my name is Bob."
    
    

在 setTimeout() 或 setInterval() 中,this 的值是什么?

  • 在 setTimeout() 或 setInterval() 中,this 的值取决于外部作用域

    const obj = {
        foo1: function () {
            return setTimeout(() => {
                console.log(this); // obj对象
            }, 100)
        },
        foo2: () => {
            return setTimeout(() => {
                console.log(this); // window
            }, 100)
        },
        foo3: function () {
            return setTimeout(function () {
                console.log(this); // obj2对象
            }.bind(obj2), 100)
        }
    }
    const obj2 = {
        name: "obj2"
    }
    

如何理解this关键字的动态绑定特性?

  • 普通函数this的值在运行时动态地确定,而不是在编译时确定。
  • 具体来说,this 的值取决于函数的调用方式而不是函数本身的定义方式
  • 注意:
    • 在使用箭头函数或 bind() 方法时
      • this 的值不会动态绑定,而是在创建函数时确定,因此会受到外层作用域的影响。

this面试题——代码题

var name = "window";
  function Person(name) {
      this.name = name;
      this.foo1 = function () {
          console.log(this.name);
      };
      this.foo2 = () => console.log(this.name);

      this.foo3 = function () {
          return function () {
              console.log(this.name);
          };
      };
      this.foo4 = function () {
          return () => {
              console.log(this.name);
          };
      };
  }
  var person1 = new Person("person1");
  var person2 = new Person("person2");

person1.foo1() //person1
person1.foo1.call(person2) //person2

person2.foo2() //person2
person2.foo2.call(person2) //person2

person1.foo3()() //window
person1.foo3.call(person2)()//window
person1.foo3().call(person2)//person2
  
person1.foo4()() // window
person1.foo4.call(person2)() //person2
person1.foo4().call(person2) //window
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值