| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 | 
							- 'use strict';
 
- /* eslint no-invalid-this: 1 */
 
- var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
 
- var toStr = Object.prototype.toString;
 
- var max = Math.max;
 
- var funcType = '[object Function]';
 
- var concatty = function concatty(a, b) {
 
-     var arr = [];
 
-     for (var i = 0; i < a.length; i += 1) {
 
-         arr[i] = a[i];
 
-     }
 
-     for (var j = 0; j < b.length; j += 1) {
 
-         arr[j + a.length] = b[j];
 
-     }
 
-     return arr;
 
- };
 
- var slicy = function slicy(arrLike, offset) {
 
-     var arr = [];
 
-     for (var i = offset || 0, j = 0; i < arrLike.length; i += 1, j += 1) {
 
-         arr[j] = arrLike[i];
 
-     }
 
-     return arr;
 
- };
 
- var joiny = function (arr, joiner) {
 
-     var str = '';
 
-     for (var i = 0; i < arr.length; i += 1) {
 
-         str += arr[i];
 
-         if (i + 1 < arr.length) {
 
-             str += joiner;
 
-         }
 
-     }
 
-     return str;
 
- };
 
- module.exports = function bind(that) {
 
-     var target = this;
 
-     if (typeof target !== 'function' || toStr.apply(target) !== funcType) {
 
-         throw new TypeError(ERROR_MESSAGE + target);
 
-     }
 
-     var args = slicy(arguments, 1);
 
-     var bound;
 
-     var binder = function () {
 
-         if (this instanceof bound) {
 
-             var result = target.apply(
 
-                 this,
 
-                 concatty(args, arguments)
 
-             );
 
-             if (Object(result) === result) {
 
-                 return result;
 
-             }
 
-             return this;
 
-         }
 
-         return target.apply(
 
-             that,
 
-             concatty(args, arguments)
 
-         );
 
-     };
 
-     var boundLength = max(0, target.length - args.length);
 
-     var boundArgs = [];
 
-     for (var i = 0; i < boundLength; i++) {
 
-         boundArgs[i] = '$' + i;
 
-     }
 
-     bound = Function('binder', 'return function (' + joiny(boundArgs, ',') + '){ 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;
 
- };
 
 
  |