call apply bind的区别

338 阅读3分钟

call、apply、bind的异同

apply()

apply方法传入的两个参数:第一个是函数上下文的对象,第二个是一个作为函数参数所组成的数组

    var obj = {
        name : 'dddd'
    }

    function func(firstName, lastName){
        console.log(firstName + ' ' + this.name + ' ' + lastName);
    }

    func.apply(obj, ['A', 'B']);    //输出结果为 A dddd B
    

我们可以看到obj作为func的函数上下文的obj。func中的this指向obj。参数 A 和 B 是放在数组中传入 func 函数,分别对应 func 参数的列表元素。

call()

call 方法第一个参数也是作为函数上下文的对象,但是后面传入的是一个参数列表,而不是单个数组。

    var obj = {
        name: 'dddd'
    }

    function func(firstName, lastName) {
        console.log(firstName + ' ' + this.name + ' ' + lastName);
    }

    func.call(obj, 'C', 'D');       // C dddd D
    

对比 apply 我们可以看到区别,C 和 D 是作为单独的参数传给 func 函数,而不是放到数组中

call和apply是使用时刻:如果参数本来就存在一个数组当中,就使用apply,如果参数比较散乱相互之间没有联系,就用call

bind()

多次bind时只认第一次bind的值

共同点:

功能角度:三者都能改变 this 指向,且第一个传递的参数都是 this 指向的对象。 传参角度:三者都采用的后续传参的形式。

不同点:

  1. call,bind后面的第一个参数是指向的对象,第二个参数是往对象传的值,bind函数中this不会被修改
  2. apply后面的第一个参数是指向的对象,第二个参数是数组,数组里面是往对象传的值(arguments 全部参数)
  3. call和apply更改this指向会自动调用,bind需要手动调用
  4. apply和call的第一个参数都是this,区别在于apply调用时,实参是放在数组中的,而通过call调用时,实参通过逗号隔开
  5. 传参方面: call 的传参是单个传递(序列),而 apply 后续传递的参数是数组形式。而 bind 与call相同。
  6. 执行方面: call 和 apply 函数的执行是直接执行的,而 bind 函数会返回一个函数,然后我 们想要调用的时候才会执行。
  7. this指向永远指向最后调用它的那个对象

apply和call用法:

  1. 更改this指向
var obj = {
            name: 'dddd'
        }

        function func() {
            console.log(this.name+'aaa');
        }

        func.call(obj); // dddd      call将this指向了obj    此时上面的this 指向obj  若是没有下方的输出obj.name  则会输出上方的this.name       ddddaaa           当下方有obj.name时会输出ddddbbb

        // 我们都知道call的第一个参数是函数上下文的对象,这里把obj传给func相当于函数里的 this //便指向了 obj 对象。
        // func.call(obj); // dddd 
        function func(){
            console.log(obj.name+'bbb')
        }
  1. 调用函数 apply、call 方法都会使函数立即执行,因此它们也可以用来调用函数
    function func() {
        console.log('dddd');
    }
    func.call();//这里我们调用func.call()相当于直接执行func函数,会直接打印dddd

  1. bind方法
    if (!Function.prototype.bind) {
     Function.prototype.bind = function () {
         var self = this,                        // 保存原函数
             context = [].shift.call(arguments), // 保存需要绑定的this上下文
             args = [].slice.call(arguments);    // 剩余的参数转为数组
         return function () {                    // 返回一个新函数
             self.apply(context,[].concat.call(args, [].slice.call(arguments)));
         }
     }
 }

参考
juejin.cn/post/694602…

juejin.cn/post/697030…