改变this指向apply()、call()、bind()三种方法

本文详细解析了JavaScript中的apply(), call()和bind()方法如何改变函数this的指向,通过实例演示了它们在不同场景的应用,以及它们之间的区别。了解这些技巧有助于在实际编程中更精准地控制函数行为。
摘要由CSDN通过智能技术生成

改变this指向apply()、call()、bind()三种方法

我们都知道在JavaScript中apply()call()、**bind()**的作用都是用来改变this指向的,那么为什么要改变this指向呢?一起看看下面的例子

var name="小明";
let obj={
 name:"小红",
 say:function () {
 console.log(this.name);
 }
};

obj.say(); //输出的结果是:小红,this指向obj对象
setTimeout(obj.say,0); //输出的结果是:小明,this指向window对象

可以观察到,正常情况下 say 方法中的 this 是指向调用它的 obj 对象的,而定时器 setTimeout 中的 say 方法中的 this 是指向window对象的(在浏览器中),这是因为 say 方法在定时器中是作为回调函数来执行的,因此回到主栈执行时是在全局执行上下文的环境中执行的,但我们需要的是 say 方法中 this 指向obj对象,因此我们需要修改 this 的指向。

  • 如果一个标准函数,也就是非箭头函数,作为某个对象的方法被调用时,这个this指向的就是函数的调用者(某个对象)

  • 箭头函数是一种特殊情况,this指向的是定义这个箭头函数的创造者,一般是window

  • 那么要改变普通函数的this指向应该怎么做呢?其实在JavaScript中提供了三种方法可以改变this指向,分别是apply()call()bind(),下面来解释一下这三种方法

    • apply()

      apply()方法:apply接收两个参数,第一个参数是this的指向,第二个参数是函数接收的参数,以数组的形式传入,且当第一个参数为null、undefined的时候,默认指向window(在浏览器中),使用apply方法改变this指向后原函数会立即执行,且此方法只是临时改变thi指向一次。

      //示例
      var name="martin";
      var obj={
       name:"lucy",
       say:function(year,place){
       console.log(this.name+" is "+year+" born from "+place);
       }
      };
      var say=obj.say;
      setTimeout(function(){
       say.apply(obj,["1996","China"])
      } ,0); //lucy is 1996 born from China,this改变指向了obj
      say("1996""China") //martin is 1996 born from China,this指向window,说明apply只是临时改变一次this指向
      
      • 当第一个参数为null或者underfind时,默认指向window,我们来做一个求数组中的最大值案例
      var arr=[1,10,5,8,3];
      console.log(Math.max.apply(null, arr)); //输出:10
      

      其中Math.max函数的参数是以参数列表形式传入,如:Math.max(1,10,5,8,3)的形式传入的,因此我们没法直接把数组当做参数,但是apply方法可以将数组参数转换成列表参数传入,从而直接求数组的最大值。

    • call()

      **call()**方法:call方法的第一个参数也是this的指向,后面传入的是一个参数列表(注意和apply传参的区别)。当一个参数为null或undefined的时候,表示指向window(在浏览器中),和apply一样,call也只是临时改变一次this指向,并立即执行。

      var arr=[1,10,5,8,3];
      console.log(Math.max.call(null,arr[0],arr[1],arr[2],arr[3],arr[4])); //10
      //采纳以参数列表的形式传入,而apply以参数数组的形式传入。
      
    • bind()

      bind()方法:bind方法和call很相似,第一个参数也是this指向,后面传入的也是一个参数列表(但是这个参数列表可以分多次传入,call则必须一次性传入所有参数),但是它改变this指向后不会立即执行,而是返回一个永久改变this指向的函数

      function fun() {
          console.log(this);  // 原来的函数this指向的是 Window
      }
      fun();
       
      function fun(a, b) {
          console.log(this); // this指向了输入的 字符串bind
          console.log(a + b);
      }
      //使用bind() 方法改变this指向,此时第一个参数是 字符串bind,那么就会指向字符串bind
      let c = fun.bind('bind', 2, 3);
      c(); // 返回新的方法,需要重新调用
      // 也可以使用下面两种方法进行调用
      // fun.bind('bind', 2, 3)();
      // fun.bind('bind')(2, 3);
      
  • apply,call,bind三者的区别

    • 三者都可以改变函数的this对象指向。
    • 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window。
    • 三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入。
    • bind 是返回绑定this之后的函数,便于稍后调用;apply 、call 则是立即执行 。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值