bind、apply与call三者区别

在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]))

  }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容