mixin.js 2.2 KB

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