bind函数的实现

107 阅读1分钟

js的bind函数的作用和特点

1.改变原函数的 this 指向,即绑定 this 2.返回原函数的拷贝 3.当 new 调用绑定函数的时候,thisArg 参数无效。也就是 new 操作符修改 this 指向的优先级更高

this 绑定有 4 种绑定规则及优先级

默认绑定<隐式绑定<显式绑定<new 绑定

if (!Function.prototype.bind) (function(){
      var ArrayPrototypeSlice = Array.prototype.slice;
      Function.prototype.bind = function(otherThis) {
        if (typeof this !== 'function') {
          // closest thing possible to the ECMAScript 5
          // internal IsCallable function
          throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
        }
	  // this 是需要被绑定的原函数
      var baseArgs= ArrayPrototypeSlice.call(arguments, 1),
      baseArgsLength = baseArgs.length,
      fToBind = this,
      fNOP    = function() {},
      fBound  = function() {
        // 修改参数数组长度后合并参数
        baseArgs.length = baseArgsLength; // reset to default base arguments
        baseArgs.push.apply(baseArgs, arguments); 
		// 判断绑定后的函数的调用方式,普通调用或者new调用
		// 1.普通调用:this指向window或undefined,
        // 2.new调用this指向new表达式返回的新对象obj,此新对象obj的原型对象为obj.__proto__
        // obj.__proto__ === fBound.prototype ===fNOP.prototype
        return fToBind.apply(
               fNOP.prototype.isPrototypeOf(this) ? this : otherThis, baseArgs
        );
      };

    if (this.prototype) { 
	  // this.prototype 为原函数的原型对象,设置代理函数的原型对象,用于new调用fBound时判断
      // 不是所有函数都有prototype属性,比如 Function.prototype就没有。
      fNOP.prototype = this.prototype;
    }
    fBound.prototype = new fNOP();
    return fBound;
  };
})();