restParam.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /** Used as the `TypeError` message for "Functions" methods. */
  2. var FUNC_ERROR_TEXT = 'Expected a function';
  3. /* Native method references for those with the same name as other `lodash` methods. */
  4. var nativeMax = Math.max;
  5. /**
  6. * Creates a function that invokes `func` with the `this` binding of the
  7. * created function and arguments from `start` and beyond provided as an array.
  8. *
  9. * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
  10. *
  11. * @static
  12. * @memberOf _
  13. * @category Function
  14. * @param {Function} func The function to apply a rest parameter to.
  15. * @param {number} [start=func.length-1] The start position of the rest parameter.
  16. * @returns {Function} Returns the new function.
  17. * @example
  18. *
  19. * var say = _.restParam(function(what, names) {
  20. * return what + ' ' + _.initial(names).join(', ') +
  21. * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
  22. * });
  23. *
  24. * say('hello', 'fred', 'barney', 'pebbles');
  25. * // => 'hello fred, barney, & pebbles'
  26. */
  27. function restParam(func, start) {
  28. if (typeof func != 'function') {
  29. throw new TypeError(FUNC_ERROR_TEXT);
  30. }
  31. start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
  32. return function() {
  33. var args = arguments,
  34. index = -1,
  35. length = nativeMax(args.length - start, 0),
  36. rest = Array(length);
  37. while (++index < length) {
  38. rest[index] = args[start + index];
  39. }
  40. switch (start) {
  41. case 0: return func.call(this, rest);
  42. case 1: return func.call(this, args[0], rest);
  43. case 2: return func.call(this, args[0], args[1], rest);
  44. }
  45. var otherArgs = Array(start + 1);
  46. index = -1;
  47. while (++index < start) {
  48. otherArgs[index] = args[index];
  49. }
  50. otherArgs[start] = rest;
  51. return func.apply(this, otherArgs);
  52. };
  53. }
  54. module.exports = restParam;