| 'use strict'; |
| var aFunction = require('../internals/a-function'); |
| var isObject = require('../internals/is-object'); |
| |
| var slice = [].slice; |
| var factories = {}; |
| |
| var construct = function (C, argsLength, args) { |
| if (!(argsLength in factories)) { |
| for (var list = [], i = 0; i < argsLength; i++) list[i] = 'a[' + i + ']'; |
| // eslint-disable-next-line no-new-func |
| factories[argsLength] = Function('C,a', 'return new C(' + list.join(',') + ')'); |
| } return factories[argsLength](C, args); |
| }; |
| |
| // `Function.prototype.bind` method implementation |
| // https://tc39.github.io/ecma262/#sec-function.prototype.bind |
| module.exports = Function.bind || function bind(that /* , ...args */) { |
| var fn = aFunction(this); |
| var partArgs = slice.call(arguments, 1); |
| var boundFunction = function bound(/* args... */) { |
| var args = partArgs.concat(slice.call(arguments)); |
| return this instanceof boundFunction ? construct(fn, args.length, args) : fn.apply(that, args); |
| }; |
| if (isObject(fn.prototype)) boundFunction.prototype = fn.prototype; |
| return boundFunction; |
| }; |