function-bind.js 1.4 KB

12345678910111213141516171819202122232425262728293031323334
  1. 'use strict';
  2. var global = require('../internals/global');
  3. var uncurryThis = require('../internals/function-uncurry-this');
  4. var aCallable = require('../internals/a-callable');
  5. var isObject = require('../internals/is-object');
  6. var hasOwn = require('../internals/has-own-property');
  7. var arraySlice = require('../internals/array-slice');
  8. var NATIVE_BIND = require('../internals/function-bind-native');
  9. var Function = global.Function;
  10. var concat = uncurryThis([].concat);
  11. var join = uncurryThis([].join);
  12. var factories = {};
  13. var construct = function (C, argsLength, args) {
  14. if (!hasOwn(factories, argsLength)) {
  15. for (var list = [], i = 0; i < argsLength; i++) list[i] = 'a[' + i + ']';
  16. factories[argsLength] = Function('C,a', 'return new C(' + join(list, ',') + ')');
  17. } return factories[argsLength](C, args);
  18. };
  19. // `Function.prototype.bind` method implementation
  20. // https://tc39.es/ecma262/#sec-function.prototype.bind
  21. module.exports = NATIVE_BIND ? Function.bind : function bind(that /* , ...args */) {
  22. var F = aCallable(this);
  23. var Prototype = F.prototype;
  24. var partArgs = arraySlice(arguments, 1);
  25. var boundFunction = function bound(/* args... */) {
  26. var args = concat(partArgs, arraySlice(arguments));
  27. return this instanceof boundFunction ? construct(F, args.length, args) : F.apply(that, args);
  28. };
  29. if (isObject(Prototype)) boundFunction.prototype = Prototype;
  30. return boundFunction;
  31. };