mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-08 02:17:48 +00:00
Add bindCallback and setCallbackData.
This commit is contained in:
220
lodash.js
220
lodash.js
@@ -1789,71 +1789,35 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base implementation of `_.callback`.
|
* The base implementation of `_.callback` which supports specifying the
|
||||||
|
* number of arguments to provide to `func`.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param {*} [func=_.identity] The value to convert to a callback.
|
* @param {*} [func=_.identity] The value to convert to a callback.
|
||||||
* @param {*} [thisArg] The `this` binding of the created callback.
|
* @param {*} [thisArg] The `this` binding of `func`.
|
||||||
* @param {number} [argCount] The number of arguments the callback accepts.
|
* @param {number} [argCount] The number of arguments to provide to `func`.
|
||||||
* @returns {Function} Returns the new function.
|
* @returns {Function} Returns the new function.
|
||||||
*/
|
*/
|
||||||
function baseCallback(func, thisArg, argCount) {
|
function baseCallback(func, thisArg, argCount) {
|
||||||
var type = typeof func;
|
var type = typeof func;
|
||||||
|
|
||||||
if (type == 'function') {
|
if (type == 'function') {
|
||||||
if (typeof thisArg == 'undefined') {
|
var data = typeof thisArg != 'undefined' && getData(func);
|
||||||
return func;
|
|
||||||
}
|
|
||||||
var data = getData(func);
|
|
||||||
if (typeof data == 'undefined') {
|
if (typeof data == 'undefined') {
|
||||||
var support = lodash.support;
|
setCallbackData(func);
|
||||||
if (support.funcNames) {
|
|
||||||
data = !func.name;
|
|
||||||
}
|
|
||||||
data = data || !support.funcDecomp;
|
|
||||||
if (!data) {
|
|
||||||
var source = fnToString.call(func);
|
|
||||||
if (!support.funcNames) {
|
|
||||||
data = !reFuncName.test(source);
|
|
||||||
}
|
|
||||||
if (!data) {
|
|
||||||
// Check if `func` references the `this` keyword and store the result.
|
|
||||||
data = reThis.test(source) || isNative(func);
|
|
||||||
baseSetData(func, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Exit early if there are no `this` references or `func` is bound.
|
// Avoid binding if there are no `this` references or `func` is already bound.
|
||||||
if (data === false || (data !== true && data[1] & BIND_FLAG)) {
|
return (data === false || (data !== true && data[1] & BIND_FLAG))
|
||||||
return func;
|
? func
|
||||||
}
|
: bindCallback(func, thisArg, argCount);
|
||||||
switch (argCount) {
|
|
||||||
case 1: return function(value) {
|
|
||||||
return func.call(thisArg, value);
|
|
||||||
};
|
|
||||||
case 3: return function(value, index, collection) {
|
|
||||||
return func.call(thisArg, value, index, collection);
|
|
||||||
};
|
|
||||||
case 4: return function(accumulator, value, index, collection) {
|
|
||||||
return func.call(thisArg, accumulator, value, index, collection);
|
|
||||||
};
|
|
||||||
case 5: return function(value, other, key, object, source) {
|
|
||||||
return func.call(thisArg, value, other, key, object, source);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return function() {
|
|
||||||
return func.apply(thisArg, arguments);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
if (func == null) {
|
if (func == null) {
|
||||||
return identity;
|
return identity;
|
||||||
}
|
}
|
||||||
// Handle "_.pluck" and "_.where" style callback shorthands.
|
// Handle "_.pluck" and "_.where" style callback shorthands.
|
||||||
if (type == 'object') {
|
return type == 'object'
|
||||||
// baseMatches
|
? baseMatches(func, argCount)
|
||||||
return matches(func);
|
: baseProperty(argCount ? String(func) : func);
|
||||||
}
|
|
||||||
return (argCount ? baseProperty : property)(func);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2404,11 +2368,11 @@
|
|||||||
* @param {Object} source The object to inspect.
|
* @param {Object} source The object to inspect.
|
||||||
* @param {Array} props The source property names to match.
|
* @param {Array} props The source property names to match.
|
||||||
* @param {Array} values The source values to match.
|
* @param {Array} values The source values to match.
|
||||||
|
* @param {Array} strictCompareFlags Strict comparison flags for source values.
|
||||||
* @param {Function} [customizer] The function to customize comparing objects.
|
* @param {Function} [customizer] The function to customize comparing objects.
|
||||||
* @param {Array} [strictCompareFlags=[]] Strict comparison flags for source values.
|
|
||||||
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
|
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
|
||||||
*/
|
*/
|
||||||
function baseIsMatch(object, props, values, customizer, strictCompareFlags) {
|
function baseIsMatch(object, props, values, strictCompareFlags, customizer) {
|
||||||
var index = -1,
|
var index = -1,
|
||||||
length = props.length;
|
length = props.length;
|
||||||
|
|
||||||
@@ -2463,6 +2427,45 @@
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base implementation of `_.matches` which supports specifying whether
|
||||||
|
* `source` is cloned.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} source The object of property values to match.
|
||||||
|
* @param {boolean} [isCloned] Specify cloning the source object.
|
||||||
|
* @returns {Function} Returns the new function.
|
||||||
|
*/
|
||||||
|
function baseMatches(source, isCloned) {
|
||||||
|
var props = keys(source),
|
||||||
|
length = props.length;
|
||||||
|
|
||||||
|
if (length == 1) {
|
||||||
|
var key = props[0],
|
||||||
|
value = source[key];
|
||||||
|
|
||||||
|
if (isStrictComparable(value)) {
|
||||||
|
return function(object) {
|
||||||
|
return object != null && value === object[key] && hasOwnProperty.call(object, key);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var notCloned = !isCloned,
|
||||||
|
values = Array(length),
|
||||||
|
strictCompareFlags = Array(length);
|
||||||
|
|
||||||
|
while (length--) {
|
||||||
|
value = source[props[length]];
|
||||||
|
var isStrict = isStrictComparable(value);
|
||||||
|
|
||||||
|
values[length] = (isStrict || notCloned) ? value : baseClone(value, true, clonePassthru);
|
||||||
|
strictCompareFlags[length] = isStrict;
|
||||||
|
}
|
||||||
|
return function(object) {
|
||||||
|
return baseIsMatch(object, props, values, strictCompareFlags);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base implementation of `_.merge` without support for argument juggling,
|
* The base implementation of `_.merge` without support for argument juggling,
|
||||||
* multiple sources, and `this` binding `customizer` functions.
|
* multiple sources, and `this` binding `customizer` functions.
|
||||||
@@ -2527,7 +2530,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base implementation of `_.property` which doesn't coerce `key` to a string.
|
* The base implementation of `_.property` which does not coerce `key` to a string.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param {string} key The name of the property to retrieve.
|
* @param {string} key The name of the property to retrieve.
|
||||||
@@ -2770,6 +2773,36 @@
|
|||||||
return high;
|
return high;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A specialized version of `_.bind` for callbacks with support for specifying
|
||||||
|
* the number of arguments to provide to `func`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Function} func The function to bind.
|
||||||
|
* @param {*} thisArg The `this` binding of `func`.
|
||||||
|
* @param {number} [argCount] The number of arguments to provide to `func`.
|
||||||
|
* @returns {Function} Returns the new function.
|
||||||
|
*/
|
||||||
|
function bindCallback(func, thisArg, argCount) {
|
||||||
|
switch (argCount) {
|
||||||
|
case 1: return function(value) {
|
||||||
|
return func.call(thisArg, value);
|
||||||
|
};
|
||||||
|
case 3: return function(value, index, collection) {
|
||||||
|
return func.call(thisArg, value, index, collection);
|
||||||
|
};
|
||||||
|
case 4: return function(accumulator, value, index, collection) {
|
||||||
|
return func.call(thisArg, accumulator, value, index, collection);
|
||||||
|
};
|
||||||
|
case 5: return function(value, other, key, object, source) {
|
||||||
|
return func.call(thisArg, value, other, key, object, source);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return function() {
|
||||||
|
return func.apply(thisArg, arguments);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a clone of the given array buffer.
|
* Creates a clone of the given array buffer.
|
||||||
*
|
*
|
||||||
@@ -3220,7 +3253,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specialized version of `baseIsEqualDeep`, for arrays-only, which supports
|
* A specialized version of `baseIsEqualDeep` for arrays with support for
|
||||||
* partial deep comparisons.
|
* partial deep comparisons.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
@@ -3312,7 +3345,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specialized version of `baseIsEqualDeep`, for objects-only, which supports
|
* A specialized version of `baseIsEqualDeep` for objects with support for
|
||||||
* partial deep comparisons.
|
* partial deep comparisons.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
@@ -3772,6 +3805,34 @@
|
|||||||
};
|
};
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A specialized version of `setData` for callbacks which sets metadata to
|
||||||
|
* indicate whether `func` is eligible for `this` binding.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Function} func The function to associate metadata with.
|
||||||
|
* @returns {Function} Returns `func`.
|
||||||
|
*/
|
||||||
|
function setCallbackData(func) {
|
||||||
|
var support = lodash.support;
|
||||||
|
if (support.funcNames) {
|
||||||
|
var data = !func.name;
|
||||||
|
}
|
||||||
|
data = data || !support.funcDecomp;
|
||||||
|
if (!data) {
|
||||||
|
var source = fnToString.call(func);
|
||||||
|
if (!support.funcNames) {
|
||||||
|
data = !reFuncName.test(source);
|
||||||
|
}
|
||||||
|
if (!data) {
|
||||||
|
// Check if `func` references the `this` keyword and store the result.
|
||||||
|
data = reThis.test(source) || isNative(func);
|
||||||
|
baseSetData(func, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A fallback implementation of `_.isPlainObject` which checks if `value`
|
* A fallback implementation of `_.isPlainObject` which checks if `value`
|
||||||
* is an object created by the `Object` constructor or has a `[[Prototype]]`
|
* is an object created by the `Object` constructor or has a `[[Prototype]]`
|
||||||
@@ -6623,7 +6684,7 @@
|
|||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @category Function
|
* @category Function
|
||||||
* @param {Function} func The function to bind.
|
* @param {Function} func The function to bind.
|
||||||
* @param {*} [thisArg] The `this` binding of `func`.
|
* @param {*} thisArg The `this` binding of `func`.
|
||||||
* @param {...*} [args] The arguments to be partially applied.
|
* @param {...*} [args] The arguments to be partially applied.
|
||||||
* @returns {Function} Returns the new bound function.
|
* @returns {Function} Returns the new bound function.
|
||||||
* @example
|
* @example
|
||||||
@@ -7910,11 +7971,13 @@
|
|||||||
* // => true
|
* // => true
|
||||||
*/
|
*/
|
||||||
function isMatch(object, source, customizer, thisArg) {
|
function isMatch(object, source, customizer, thisArg) {
|
||||||
var props = keys(source);
|
var props = keys(source),
|
||||||
|
length = props.length;
|
||||||
|
|
||||||
if (typeof customizer == 'function') {
|
if (typeof customizer == 'function') {
|
||||||
customizer = baseCallback(customizer, thisArg, 3);
|
customizer = baseCallback(customizer, thisArg, 3);
|
||||||
}
|
}
|
||||||
else if (props.length == 1) {
|
else if (length == 1) {
|
||||||
var key = props[0],
|
var key = props[0],
|
||||||
value = source[key];
|
value = source[key];
|
||||||
|
|
||||||
@@ -7922,8 +7985,14 @@
|
|||||||
return object != null && value === object[key] && hasOwnProperty.call(object, key);
|
return object != null && value === object[key] && hasOwnProperty.call(object, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var values = baseValues(source, props);
|
var values = Array(length),
|
||||||
return baseIsMatch(object, props, values, customizer);
|
strictCompareFlags = Array(length);
|
||||||
|
|
||||||
|
while (length--) {
|
||||||
|
value = values[length] = source[props[length]];
|
||||||
|
strictCompareFlags[length] = isStrictComparable(value);
|
||||||
|
}
|
||||||
|
return baseIsMatch(object, props, values, strictCompareFlags, customizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9912,7 +9981,7 @@
|
|||||||
* @alias iteratee
|
* @alias iteratee
|
||||||
* @category Utility
|
* @category Utility
|
||||||
* @param {*} [func=_.identity] The value to convert to a callback.
|
* @param {*} [func=_.identity] The value to convert to a callback.
|
||||||
* @param {*} [thisArg] The `this` binding of the created callback.
|
* @param {*} [thisArg] The `this` binding of `func`.
|
||||||
* @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
|
* @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
|
||||||
* @returns {Function} Returns the new function.
|
* @returns {Function} Returns the new function.
|
||||||
* @example
|
* @example
|
||||||
@@ -10008,36 +10077,7 @@
|
|||||||
* // => { 'user': 'barney', 'age': 36 }
|
* // => { 'user': 'barney', 'age': 36 }
|
||||||
*/
|
*/
|
||||||
function matches(source) {
|
function matches(source) {
|
||||||
var props = keys(source),
|
return baseMatches(source, true);
|
||||||
length = props.length;
|
|
||||||
|
|
||||||
if (length == 1) {
|
|
||||||
var key = props[0],
|
|
||||||
value = source[key];
|
|
||||||
|
|
||||||
if (isStrictComparable(value)) {
|
|
||||||
return function(object) {
|
|
||||||
return object != null && value === object[key] && hasOwnProperty.call(object, key);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var values = Array(length),
|
|
||||||
strictCompareFlags = Array(length);
|
|
||||||
|
|
||||||
while (length--) {
|
|
||||||
value = source[props[length]];
|
|
||||||
var isStrict = isStrictComparable(value);
|
|
||||||
|
|
||||||
values[length] = isStrict ? value : baseClone(value, true, clonePassthru);
|
|
||||||
strictCompareFlags[length] = isStrict;
|
|
||||||
}
|
|
||||||
return baseMatches(props, values, strictCompareFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
function baseMatches(source, props, values, strictCompareFlags) {
|
|
||||||
return function(object) {
|
|
||||||
return baseIsMatch(object, props, values, null, strictCompareFlags);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user