SOURCE

Function.prototype.testBind = function(that) {
  var _this = this
  var args = Array.prototype.slice.apply(arguments, [1]) // bind的第一根参数是执行域,剩下才是参数
  return function (){
   return _this.apply(that, args.concat(Array.prototype.slice(arguments, [0]))) // 拼接两个函数的参数
  } 
}

var testObj = function(a, b) {
   console.log('作用域绑定 '+ this.value)
    console.log('testBind参数传递 '+ a.value2)
    console.log('调用参数传递 ' + b)
}
var obj = {
  value: '作用域'
}
var func = testObj.bind(obj, {value2: 'a'})
func('fasd')


Function.prototype.mybind = function(){
  // 1、保存函数
  var _this = this;
  // 2、保存目标对象
  var context = arguments[0]||window;
  // 3、保存目标对象之外的参数,将其转化为数组;
  var rest = Array.prototype.slice.call(arguments,1);
  // 4、返回一个待执行的函数
  return function F(){
  // 5、将二次传递的参数转化为数组;
    var rest2 = Array.prototype.slice.call(arguments)
    //6、用apply调用第一步保存的函数,并绑定this,传递合并的参数数组
    _this.apply(context,rest.concat(rest2));
  }
}

// es6写法:
Function.prototype.myBind = function(ctx, ...argv1) {
    return (...argv2) => {
        return this.call(ctx, ...argv1, ...argv2)
    }
}
console 命令行工具 X clear

                    
>
console