美文网首页
bind、apply与call三者区别

bind、apply与call三者区别

作者: 六月繁花开 | 来源:发表于2018-08-27 19:31 被阅读12次

    在JS中,这三者都是用来改变函数的this对象的指向的,他们有什么样的区别呢。

    在说区别之前还是先总结一下三者的相似之处:

    1、都是用来改变函数的this对象的指向的。

    2、第一个参数都是this要指向的对象。

    3、都可以利用后续参数传参。

    那么他们的区别在哪里的,先看一个例子。

        var xw = {

                            name : "小王",

                            gender : "男",

                            age : 24,

                            say : function() {

                                    alert(this.name + " , " + this.gender + " ,今年" + this.age);                                

                            }

                    }

                    var xh = {

                            name : "小红",

                            gender : "女",

                            age : 18

                    }

                    xw.say();

    那么如何用xw的say方法来显示xh的数据呢。

    对于call可以这样:

    xw.say.call(xh);

    复制代码

    对于apply可以这样:

    xw.say.apply(xh);

    复制代码

    而对于bind来说需要这样:

    xw.say.bind(xh)();

    总之:bind与apply、call最大的区别就是:bind不会立即调用,其他两个会立即调用,apply与call的区别是apply第二个是参数组,但是在确定的参数下,还是最好用call,call的效果会更高,但是在函数的延展性上使用apply更好

    手写一个call方法

    考虑两点

    第一个参数为undefined或null的时候,那么会转变为window

    改变了this执行,让新的对象可以执行该函数。

    Function.prototype.myCall = function(context) {

      // 判断是否是undefined和null

      if (typeof context === 'undefined' || context === null) {

        context = window

      }

      context.fn = this

      let args = [...arguments].slice(1)

      let result = context.fn(...args)

      delete context.fn

      return result

    }

    apply的实现

    Function.prototype.myApply = function(context) {

      if (typeof context === 'undefined' || context === null) {

        context = window

      }

      context.fn = this

      let args = arguments[1]

      let result

      if (args) {

        result = context.fn(...args)

      } else {

        result = context.fn()

      }

      delete context.fn

      return result

    }

    bind实现

    这里需要注意下,因为bind转换后的函数可以作为构造函数使用,此时this应该指向构造出的实例,而bind函数绑定的第一个参数。

    Function.prototype.myBind = function(context) {

      if (typeof this !== 'function') {

        throw new TypeError('Error')

      }

      let _this = this

      let args = [...arguments].slice(1)

      return function F() {

        // 判断是否被当做构造函数使用

        if (this instanceof F) {

          return _this.apply(this, args.concat([...arguments]))

        }

        return _this.apply(context, args.concat([...arguments]))

      }

    }

    相关文章

      网友评论

          本文标题:bind、apply与call三者区别

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