var arrayCopy = require('../internal/arrayCopy'), arrayPush = require('../internal/arrayPush'), baseFunctions = require('../internal/baseFunctions'), isFunction = require('../lang/isFunction'), isObject = require('../lang/isObject'), keys = require('../object/keys'); /** * Adds all own enumerable function properties of a source object to the * destination object. If `object` is a function then methods are added to * its prototype as well. * * **Note:** Use `_.runInContext` to create a pristine `lodash` function to * avoid conflicts caused by modifying the original. * * @static * @memberOf _ * @category Utility * @param {Function|Object} [object=lodash] The destination object. * @param {Object} source The object of functions to add. * @param {Object} [options] The options object. * @param {boolean} [options.chain=true] Specify whether the functions added * are chainable. * @returns {Function|Object} Returns `object`. * @example * * function vowels(string) { * return _.filter(string, function(v) { * return /[aeiou]/i.test(v); * }); * } * * _.mixin({ 'vowels': vowels }); * _.vowels('fred'); * // => ['e'] * * _('fred').vowels().value(); * // => ['e'] * * _.mixin({ 'vowels': vowels }, { 'chain': false }); * _('fred').vowels(); * // => ['e'] */ function mixin(object, source, options) { var methodNames = baseFunctions(source, keys(source)); var chain = true, index = -1, isFunc = isFunction(object), length = methodNames.length; if (options === false) { chain = false; } else if (isObject(options) && 'chain' in options) { chain = options.chain; } while (++index < length) { var methodName = methodNames[index], func = source[methodName]; object[methodName] = func; if (isFunc) { object.prototype[methodName] = (function(func) { return function() { var chainAll = this.__chain__; if (chain || chainAll) { var result = object(this.__wrapped__), actions = result.__actions__ = arrayCopy(this.__actions__); actions.push({ 'func': func, 'args': arguments, 'thisArg': object }); result.__chain__ = chainAll; return result; } return func.apply(object, arrayPush([this.value()], arguments)); }; }(func)); } } return object; } module.exports = mixin;