call、apply、bind的用法和区别

262 阅读2分钟

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

call、apply、bind都是改变this指向的方法 相同:都是改变函数上下文this指向

不同:call、apply的区别:接受参数的方式不一样。 bind:不立即执行。而apply、call 立即执行。

用法:

  1. call:
  • 非严格模式 如果不传参数,或者第一个参数是null或nudefined,this都指向window
    let fn = function(a,b){
        console.log(this,a,b);
    }
    let obj = {name:"obj"};
    fn.call(obj,1,2);    // this:obj    a:1         b:2
    fn.call(1,2);        // this:1      a:2         b:undefined
    fn.call();           // this:window a:undefined b:undefined
    fn.call(null);       // this=window a=undefined b=undefined
    fn.call(undefined);  // this=window a=undefined b=undefined
  • 严格模式 第一个参数是谁,this就指向谁,包括null和undefined,如果不传参数this就是undefined
    "use strict"
    let fn = function(a,b){
        console.log(this,a,b);
    }
    let obj = {name:"obj"};
    fn.call(obj,1,2);   // this:obj        a:1          b:2
    fn.call(1,2);       // this:1          a:2          b=undefined
    fn.call();          // this:undefined  a:undefined  b:undefined
    fn.call(null);      // this:null       a:undefined  b:undefined
    fn.call(undefined); // this:undefined  a:undefined  b:undefined
  1. apply: 和call基本上一致,唯一区别在于传参方式 apply把需要传递给fn的参数放到一个数组(或者类数组)中传递进去,虽然写的是一个数组,但是也相当于给fn一个个的传递
    fn.call(obj, 1, 2);
    fn.apply(obj, [1, 2]);
  1. bind: 语法和call一模一样,区别在于立即执行还是等待执行,bind不兼容IE6~8

    fn.call(obj, 1, 2); // 改变fn中的this,并且把fn立即执行
    fn.bind(obj, 1, 2); // 改变fn中的this,fn并不执行

this改变为obj了,但是绑定的时候立即执行,当触发点击事件的时候执行的是fn的返回值undefined

    document.onclick = fn.call(obj);

bind会把fn中的this预处理为obj,此时fn没有执行,当点击的时候才会把fn执行

document.onclick = fn.bind(obj);