• 解析JavaScript中apply和call以及bind


    函数调用方法

    在谈论JavaScript中apply、call和bind这三兄弟之前,我想先说下,函数的调用方式有哪些:

    • 作为函数
    • 作为方法
    • 作为构造函数
    • 通过它们的call()和apply()方法间接调用

    前面的三种调用方法,我们都知道且不在这篇文章的讨论范围内,就不说了。

    下面我们来说说这第四种调用方法

    通过call()和apply()间接调用

    其实,我们可以将这两个函数看做是某个对象的方法,通过调用方法的方式来间接调用函数:

    function f(){}
    
    f.call(o);
    f.apply(o);

    call()和apply()的第一个参数是要调用函数的母对象,它是调用上下文,在函数体内通过this来获得对它的引用。

    那么他们是一样的,还是有区别的,还有bind方法呢?君莫急,下面详细的解析他们三者的区别和联系。

    call()

    call()方法给调用它的方法指定特定的this指针(习惯用语,不要和我纠结它的正确性)和参数。例如有这么一个函数:

    var fn = function (arg1, arg2) {
      console.log(this, arg1, arg2);      
    }

    我来调用它:

    fn.call(null, 'Skylor', 'min');        //1
    fn.call(undefined, 'Skylor', 'min');   //2
    
    var fx = function() {}
    
    fn.call(fx, 'Skylor', 'min');          //3

    这三个call方法的返回值是什么呢?不废话,请看:

    1.  null "Skylor" "min"
    2.  undefined "Skylor" "min"
    3.  fx "Skylor" "min"

    真的是这样吗,机智的你,去浏览器控制台小试了一下,我去,你这坑货,不是这样的:

    chrome
    1.  Window "Skylor" "min"
    2.  Window "Skylor" "min"
    3.  fx "Skylor" "min"

    好吧,你机智。但这已经很好的说明了call方法了。(window很高级,微软偷笑中...)

    我们注意到call方法,第一个参数是指定this指针,后面每个参数指定需要的参数,注意我用的是“每个”,这意味着你需要几个参数就要想调用函数那样,一个个参数写进去。

    apply()

    apply()是call()的兄弟啊,其他地方长的都一样,都是男的,就一个地方不一样。先看例子:

    fn.apply(null, ['Skylor', 'min']); //1
    fn.apply(fx, ['Skylor', 'min']);   //2

    哥们,你是不是写错了,多了个中括号啊。不,不,不,这就是他和call长的不一样的地方,它的第二个参数是个需要的参数Array。

    bind()

    bind()嘛,他们三个不是仨兄弟嘛,,这个我懂,blabla....不不不,它是和apply、call结拜的兄弟,不是亲兄弟。

    当然,bind方法也是允许你指定this指针,但是它不是调用函数,而是返回一个(或者说是拷贝调用它的函数的函数,并给这个函数指定特定的this指针和参数。惯例,例子说明一切:

    var fnbound = fn.bind(null, 'Skylor', 'min');

    这时,fnbound是一个函数,一个this指向null,参数为['Skylor', 'min']的另一个函数。调用之:

    fnbound();

    结果:

    null, 'Skylor', 'min'

    不要和我纠结Window的事了。。。。。

    bind和其他两个兄弟不一样的地方,是,它不是调用函数,而是返回一个新的函数,同样,它也是指定this指针和参数的,指定参数的方式和call一样,是一个一个来的。

    最后来一个例子呗:

    var shoppingCart = (function(){
             var _calculatePrice = function () {
                        return this.price * this.amount;
             };
    
             return {
                        calculatePrice : _calculatePrice
             }
    })();
    
    
    var goods = {
               name : ‘hammer’,
               price: 199,
               amount : 2
    };
    
    shoppingCart.calculatePrice.call(goods);

    OK,以上是我的见解,如有不正确的地方,欢迎指正和批评,不甚欢喜与感谢。By Skylormin

  • 相关阅读:
    TCP/IP||ARP/RARP
    TCP/IP||IP
    TCP/IP||链路层
    Struts||IQ
    SpringMVC||IQ
    TCP/IP Basic
    Spring||Mails
    Spring||Quartz
    jQuery Ajax 方法应用。
    html5的离线储存应用.
  • 原文地址:https://www.cnblogs.com/skylor/p/4723612.html
Copyright © 2020-2023  润新知