js的apply,call,bind的this指向详解

5 阅读1分钟

结论:

  1. 三者都可以改变函数的 this 对象指向。
  2. 三者第⼀个参数都是 this 要指向的对象,如果如果没有这个参数或参数为 undefined 或 null ,则默认指向全局 window。
  3. 三者都可以传参,但是 apply 是数组,⽽ call 是参数列表,且 apply 和 call 是⼀次性传⼊参数,⽽ bind 可以分为多次传⼊。
  4. bind 是返回绑定this之后的函数, apply 、 call 则是⽴即执⾏。

什么情况下需要改变this的指向

var name = "lucy";
    var obj = {
     name: "martin",
     say: function () {
     console.log(this.name);
    }
};
obj.say(); // martin,this 指向 obj 对象
setTimeout(obj.say,0); // lucy,this 指向 window 对象
//正常情况 say ⽅法输出 martin
//但是我们把 say 放在 setTimeout ⽅法中,在定时器中是作为回调函数来执⾏的,因此回到主栈执
//⾏时是在全局执⾏上下⽂的环境中执⾏的,这时候 this 指向 window ,所以输出 lucy
//我们实际需要的是 this 指向 obj 对象,这时候就需要该改变 this 指向
setTimeout(obj.say.bind(obj),0); //martin,this指向obj对象

代码详解

  1. apply
function fn(...args){
 console.log(this,args);
}

let obj = {
 myname:"张三"
}

fn.apply(obj,[1,2]); //打印出obj对象,1,2;
fn(1,2) // 这里的this指向window
  1. call
function fn(...args){
 console.log(this,args);
}
let obj = {
 myname:"张三"
}
fn.call(obj,1,2); //打印出obj对象,1,2。 this会变成传⼊的obj,单独传入参数;
fn(1,2) // this指向window
  1. bind
function fn(...args){
 console.log(this,args);
}
let obj = {
 myname:"张三"
}
const bindFn = fn.bind(obj); // this 也会变成传⼊的obj ,bind不是⽴即执⾏需要执⾏⼀次
bindFn(1,2) // this指向obj
fn(1,2) // this指向window