call、apply、bind的区别,模拟call、apply和bind的实现

bind:bind绑定完this的指向后会返回一个新的函数体,不会被立即调用
 
call&apply:绑定完this的指向后会立即调用
 
call与apply的区别:
    call:第一个参数是this的指向,第二个以及后面的所有参数需要一个个进行传递
 
    apply:第一个参数是this的指向,第二个参数是一个数组
 
不传参的方法:
Function.prototype.bind2 = function (context) {
    var self = this;
    return function () {
        return self.call(context);
    }

}
传参的方法:
Function.prototype.myBind = function (objCtx) {
    if (typeof this !== 'function') {
        throw new TypeError('Error');
    }
    let ctx = objCtx || window;
    let _this = this;
    let args = [...arguments].slice(1);
    
    let Fbind = function () {
        let self = this instanceof Fbind ? this : ctx;
        return _this.apply(self, args.concat(...arguments));
        // 这里可以使用 call 方法
        // let bindArgs = args.concat(...arguments);
        // return _this.call(self, ...bindArgs);
    }
    
    let f = function () {};
    f.prototype = this.prototype;
    Fbind.prototype = new f();
    
    return Fbind;
}
 

以上就是 call 的思路,apply 的实现也类似

不传参的方法:
Function.prototype.bind2 = function (context) {
    var self = this;
    return function () {
        return self.apply(context);
    }

}
传参的方法:
Function.prototype.myBind = function (objCtx) {
    if (typeof this !== 'function') {
        throw new TypeError('Error');
    }
    let ctx = objCtx || window;
    let _this = this;
    let args = [...arguments].slice(1);
    
    let Fbind = function () {
        let self = this instanceof Fbind ? this : ctx;
        return _this.apply(self, args.concat(...arguments));
        // 这里可以使用 call 方法
        // let bindArgs = args.concat(...arguments);
        // return _this.apply(self, ...bindArgs);
    }
    
    let f = function () {};
    f.prototype = this.prototype;
    Fbind.prototype = new f();
    
    return Fbind;
}
 

bind 和其他两个方法作用也是一致的,只是该方法会返回一个函数。并且我们可以通过 bind 实现柯里化。

同样的,也来模拟实现下 bind

 
Function.prototype.myBind = function (context) {
  if (typeof this !== 'function') {
    throw new TypeError('Error')
  }
  var _this = this
  var args = [...arguments].slice(1)
  // 返回一个函数
  return function F() {
    // 因为返回了一个函数,我们可以 new F(),所以需要判断
    if (this instanceof F) {
      return new _this(...args, ...arguments)
    }
    return _this.apply(context, args.concat(...arguments))
  }
}

 

如何准确的判断一个对象是一个什么类型的?
1、typeof  

2、instanceof    var a=[1,2];console.log(a instanceof Array)  //true
3、Object.prototype.toString.call()    var arr = [10,20,03,04]; var fn = function(){} var img = new Image() var d = new Date() console.log(arr.toString()) console.log(Object.prototype.toString.call(d))

 

 
posted @ 2018-12-08 09:32  HOUY  阅读(469)  评论(0编辑  收藏  举报