| 'use strict'; | 
|   | 
| /* eslint no-invalid-this: 1 */ | 
|   | 
| var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible '; | 
| var slice = Array.prototype.slice; | 
| var toStr = Object.prototype.toString; | 
| var funcType = '[object Function]'; | 
|   | 
| module.exports = function bind(that) { | 
|     var target = this; | 
|     if (typeof target !== 'function' || toStr.call(target) !== funcType) { | 
|         throw new TypeError(ERROR_MESSAGE + target); | 
|     } | 
|     var args = slice.call(arguments, 1); | 
|   | 
|     var bound; | 
|     var binder = function () { | 
|         if (this instanceof bound) { | 
|             var result = target.apply( | 
|                 this, | 
|                 args.concat(slice.call(arguments)) | 
|             ); | 
|             if (Object(result) === result) { | 
|                 return result; | 
|             } | 
|             return this; | 
|         } else { | 
|             return target.apply( | 
|                 that, | 
|                 args.concat(slice.call(arguments)) | 
|             ); | 
|         } | 
|     }; | 
|   | 
|     var boundLength = Math.max(0, target.length - args.length); | 
|     var boundArgs = []; | 
|     for (var i = 0; i < boundLength; i++) { | 
|         boundArgs.push('$' + i); | 
|     } | 
|   | 
|     bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder); | 
|   | 
|     if (target.prototype) { | 
|         var Empty = function Empty() {}; | 
|         Empty.prototype = target.prototype; | 
|         bound.prototype = new Empty(); | 
|         Empty.prototype = null; | 
|     } | 
|   | 
|     return bound; | 
| }; |