美文网首页Web前端之路
js中call(),apply(),bind()的区别

js中call(),apply(),bind()的区别

作者: GDUF_XRT | 来源:发表于2017-03-08 21:23 被阅读133次

    共同点

    • call()apply()bind()三个函数都是Function实例对象的属性,也就是说存在于Function.prototype中。
    • 作用都是设置函数体内对象的值,即改变函数运行时的上下文
    • 第一个参数都是运行函数的作用域,即要指定的上下文

    区别

    Function.prototype.call()

    先来理解一下call()的作用:

    
    var name = "banana";
    var fruits = {
         name: "apple"
    };
    
    function say() {
        console.log("I'm " + this.name);
    }
    
    say();  //I'm banana
    

    此时调用say()的上下文(this)是window对象,所以输出的name为“banana”。如果我想输出name为“apple”那该怎么办?call()可以解决这个问题:

    say.call(fruits);  //I'm apple
    

    可以看出call()能改变函数运行时的this指向。
    apply()bind()亦如此。

    语法

    Function.call(thisObj,[arg1[arg2[argN]]]);

    参数

    call()有两个参数,一个(thisObj)是函数运行的作用域,另一个(arg)是传给函数的参数,传入的参数必须逐个列举出来。

    例子
    function sum(num1, num2) {
      return num1 + num2;
    }
    
    function callSum(num1, num2) {
      return sum.call(this, num1, num2);
    }
    
    console.log(callSum(10, 10));  //20
    

    Function.prototype.apply()

    apply()的作用与call()完全相同。

    语法

    Function.apply(thisObj, [argArray]);

    参数

    apply()也有两个参数,一个(thisObj)是函数运行的作用域,另一个(arg)是传给函数的参数,与'call()'不同的是传入的参数可以是arguments对象,也可以是数组。

    如果 argArray不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。

    例子
    function sum(num1, num2) {
      return num1 + num2;
    }
    
    function callSum1(num1, num2) {
      return sum.apply(this, arguments);
    }
    
    function callSum2(num1, num2) {
      return sum.apply(this, [num1, num2]);
    }
    
    console.log(callSum1(10, 10));  //20
    console.log(callSum2(10, 10));  //20
    

    可以看出,call()apply()作用一样,唯一的区别只是传入参数的形式不同。接下来看一下bind()函数。

    Function.prototype.bind()

    语法

    Function.bind(thisObj, [arg1[arg2[argN]]])

    参数

    bind()传参数方式与call()相同。但它有一个返回值,MDN上这样介绍:“返回由指定的this值和初始化参数改造的原函数拷贝。”

    例子

    有时我们需要用到函数外的作用域,这是我们一般会用_this, $this等来存储外部函数对象,如下:

    var foo = {
        num : 1,
        eventBind: function() {
            var $this = this;
            $('.class').on('click',function(event) {
                console.log($this.num);     //1
            });
        }
    }
    

    这样的做法没有问题,不过我们可以使用bind()更优雅的解决。

    var foo = {
        num : 1,
        eventBind: function() {
            $('.class').on('click',function(event) {
                console.log(this.num);     //1
            }.bind(this));
        }
    }
    

    call()apply()bind()的主要区别是:call()apply()改变上下文之后立即执行,而bind()只是返回一个函数,不执行。

    参考:

    相关文章

      网友评论

        本文标题:js中call(),apply(),bind()的区别

        本文链接:https://www.haomeiwen.com/subject/uwwmgttx.html