import createWrap from './.internal/createWrap.js' import getHolder from './.internal/getHolder.js' import replaceHolders from './.internal/replaceHolders.js' /** Used to compose bitmasks for function metadata. */ const WRAP_BIND_FLAG = 1 const WRAP_BIND_KEY_FLAG = 2 const WRAP_PARTIAL_FLAG = 32 /** * Creates a function that invokes the method at `object[key]` with `partials` * prepended to the arguments it receives. * * This method differs from `bind` by allowing bound functions to reference * methods that may be redefined or don't yet exist. See * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) * for more details. * * The `bindKey.placeholder` value, which defaults to `_` in monolithic * builds, may be used as a placeholder for partially applied arguments. * * @since 0.10.0 * @category Function * @param {Object} object The object to invoke the method on. * @param {string} key The key of the method. * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new bound function. * @example * * const object = { * 'user': 'fred', * 'greet': function(greeting, punctuation) { * return greeting + ' ' + this.user + punctuation * } * } * * const bound = bindKey(object, 'greet', 'hi') * bound('!') * // => 'hi fred!' * * object.greet = function(greeting, punctuation) { * return greeting + 'ya ' + this.user + punctuation * } * * bound('!') * // => 'hiya fred!' * * // Bound with placeholders. * const bound = bindKey(object, 'greet', _, '!') * bound('hi') * // => 'hiya fred!' */ function bindKey(object, key, ...partials) { let holders let bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG if (partials.length) { holders = replaceHolders(partials, getHolder(bindKey)) bitmask |= WRAP_PARTIAL_FLAG } return createWrap(key, bitmask, object, partials, holders) } // Assign default placeholders. bindKey.placeholder = {} export default bindKey