美文网首页
call、apply、bind的理解与区别

call、apply、bind的理解与区别

作者: 陌年滺瑾揚 | 来源:发表于2019-04-02 17:24 被阅读0次

    在JavaScript中,call、apply和bind是Function对象自带的三个方法,都是为了改变函数体内部 this 的指向。

    bind 是返回对应 函数,便于稍后调用;apply 、call则是立即调用 

    call 是把参数按顺序传递进去,而 apply 则是把参数放在数组 里。


    类(伪)数组使用数组方法

    Javascript中存在一种名为伪数组的对象结构。比较特别的是 arguments 对象,还有像调用 getElementsByTagName , document.childNodes 之类的,它们返回NodeList对象都属于伪数组。不能应用 Array下的 push , pop 等方法

    vardivElements = document.getElementsByTagName('div');//虽然 divElements 有length属性,但是他是一个伪数组,不能使用数组里面的方法

    Array.isArray(divElements);

    vardomNodes = Array.prototype.slice.call(document.getElementsByTagName('div'));// 将数组对象Array里的this指向伪数组document.getElementsByTagName('div'),

    //slice() 方法可从已有的数组中返回选定的元素,不传参数是,返回整个数组

    Array.isArray(domNodes);// true


    验证一个对象的类型可以用:

    Object.prototype.toString.call(obj)

    原因:

    这是因为toString为Object的原型方法,而Array ,function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串.....),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object上原型toString方法。


    在 Javascript 中,多次bind()是无效的。更深层次的原因,bind()的实现,相当于使用函数在内部包了一个call / apply,第二次bind()相当于再包住第一次bind(),故第二次以后的bind是无法生效的。

    当传入参数的个数是不确定的时候,这个时候就可以考虑使用 apply 或者 call,注意这里传入多少个参数是不确定的,所以使用apply是最好的

    functionlog(){

      console.log.apply(console, arguments);

    };

    log(1);    //1

    log(1,2); 

    接下来的要求是给每一个 log 消息添加一个"(app)"的前辍,比如:

    log("hello world");    //(app)hello world

      该怎么做比较优雅呢?这个时候需要想到arguments参数是个伪数组,通过 Array.prototype.slice.call 转化为标准数组,再使用数组方法unshift,像这样:

    functionlog(){

      varargs = Array.prototype.slice.call(arguments);

      args.unshift('(app)');

      console.log.apply(console, args);

    };

    区别是,当你希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用 bind() 方法。而 apply/call 则会立即执行函数。

    当函数通过Function对象的原型中继承的方法 call() 和 apply() 方法调用时, 其函数内部的this值可绑定到 call() & apply() 方法指定的第一个对象上, 如果第一个参数不是对象,JavaScript内部会尝试将其转换成对象然后指向它

    再总结一下:

    apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;

    apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;

    apply 、 call 、bind 三者都可以利用后续参数传参;

    bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。

    相关文章

      网友评论

          本文标题:call、apply、bind的理解与区别

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