| 'use strict'; |
| var aFunction = require('./_a-function') |
| , isObject = require('./_is-object') |
| , invoke = require('./_invoke') |
| , arraySlice = [].slice |
| , factories = {}; |
| |
| var construct = function(F, len, args){ |
| if(!(len in factories)){ |
| for(var n = [], i = 0; i < len; i++)n[i] = 'a[' + i + ']'; |
| factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')'); |
| } return factories[len](F, args); |
| }; |
| |
| module.exports = Function.bind || function bind(that /*, args... */){ |
| var fn = aFunction(this) |
| , partArgs = arraySlice.call(arguments, 1); |
| var bound = function(/* args... */){ |
| var args = partArgs.concat(arraySlice.call(arguments)); |
| return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that); |
| }; |
| if(isObject(fn.prototype))bound.prototype = fn.prototype; |
| return bound; |
| }; |