# 修改作用域

# bind

返回被修改this指向的函数,不会立即执行

if (!Function.prototype.bind) {
  Function.prototype.bind = function() {
    if (typeof this !== 'function') {
      throw new TypeError('only function can call');
    }
    
    // 第一个参数未绑定上下文
    var context = arguments[0];
    var slice = Array.prototype.slice;
    // 其他参数
    var args = slice.call(arguments, 1);
    // 当前函数
    var self = this;

    // 输出新的函数
    var bindFunc = function() {
      // 合并参数
      var _args = args.concat(slice.call(arguments, 0));
      // this instanceof self === true 表面函数作为构造函数使用new调用,使用当前上下文
      var ctx = this instanceof self ? this : context;
      return self.apply(ctx, _args);
    }

    function f() {};
    if (this.prototype) {
      f.prototype = this.prototype;
    }

    // 修正输出函数原型,指向原函数
    bindFunc.prototype = new f();
    return bindFunc;
  }
}
  • call
Function.prototype.call = function(context, ...args) {
  context.fn = this;
  const result = context.fn(...args);
  delete context.fn;
  return result;
}
  • apply
Function.prototype.apply = function(context, args) {
  context.fn = this;
  const result = context.fn(...args);
  delete context.fn;
  return result;
}