mixin.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. var arrayCopy = require('../internal/arrayCopy'),
  2. arrayPush = require('../internal/arrayPush'),
  3. baseFunctions = require('../internal/baseFunctions'),
  4. isFunction = require('../lang/isFunction'),
  5. isObject = require('../lang/isObject'),
  6. keys = require('../object/keys');
  7. /**
  8. * Adds all own enumerable function properties of a source object to the
  9. * destination object. If `object` is a function then methods are added to
  10. * its prototype as well.
  11. *
  12. * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
  13. * avoid conflicts caused by modifying the original.
  14. *
  15. * @static
  16. * @memberOf _
  17. * @category Utility
  18. * @param {Function|Object} [object=lodash] The destination object.
  19. * @param {Object} source The object of functions to add.
  20. * @param {Object} [options] The options object.
  21. * @param {boolean} [options.chain=true] Specify whether the functions added
  22. * are chainable.
  23. * @returns {Function|Object} Returns `object`.
  24. * @example
  25. *
  26. * function vowels(string) {
  27. * return _.filter(string, function(v) {
  28. * return /[aeiou]/i.test(v);
  29. * });
  30. * }
  31. *
  32. * _.mixin({ 'vowels': vowels });
  33. * _.vowels('fred');
  34. * // => ['e']
  35. *
  36. * _('fred').vowels().value();
  37. * // => ['e']
  38. *
  39. * _.mixin({ 'vowels': vowels }, { 'chain': false });
  40. * _('fred').vowels();
  41. * // => ['e']
  42. */
  43. function mixin(object, source, options) {
  44. var methodNames = baseFunctions(source, keys(source));
  45. var chain = true,
  46. index = -1,
  47. isFunc = isFunction(object),
  48. length = methodNames.length;
  49. if (options === false) {
  50. chain = false;
  51. } else if (isObject(options) && 'chain' in options) {
  52. chain = options.chain;
  53. }
  54. while (++index < length) {
  55. var methodName = methodNames[index],
  56. func = source[methodName];
  57. object[methodName] = func;
  58. if (isFunc) {
  59. object.prototype[methodName] = (function(func) {
  60. return function() {
  61. var chainAll = this.__chain__;
  62. if (chain || chainAll) {
  63. var result = object(this.__wrapped__),
  64. actions = result.__actions__ = arrayCopy(this.__actions__);
  65. actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
  66. result.__chain__ = chainAll;
  67. return result;
  68. }
  69. return func.apply(object, arrayPush([this.value()], arguments));
  70. };
  71. }(func));
  72. }
  73. }
  74. return object;
  75. }
  76. module.exports = mixin;