mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-12 11:57:49 +00:00
Extract common components of _.keys and _.keysIn and make _.keysIn use the Reflect.enumerate shim as a compat path for older enviros.
This commit is contained in:
167
lodash.src.js
167
lodash.src.js
@@ -142,9 +142,9 @@
|
|||||||
var contextProps = [
|
var contextProps = [
|
||||||
'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array',
|
'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array',
|
||||||
'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number',
|
'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number',
|
||||||
'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite',
|
'Object', 'Reflect', 'RegExp', 'Set', 'String', 'TypeError', 'Uint8Array',
|
||||||
'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array',
|
'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_',
|
||||||
'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap'
|
'clearTimeout', 'isFinite', 'parseFloat', 'parseInt', 'setTimeout',
|
||||||
];
|
];
|
||||||
|
|
||||||
/** Used to make template sourceURLs easier to identify. */
|
/** Used to make template sourceURLs easier to identify. */
|
||||||
@@ -743,6 +743,7 @@
|
|||||||
Math = context.Math,
|
Math = context.Math,
|
||||||
Number = context.Number,
|
Number = context.Number,
|
||||||
Object = context.Object,
|
Object = context.Object,
|
||||||
|
Reflect = context.Reflect,
|
||||||
RegExp = context.RegExp,
|
RegExp = context.RegExp,
|
||||||
String = context.String,
|
String = context.String,
|
||||||
TypeError = context.TypeError;
|
TypeError = context.TypeError;
|
||||||
@@ -782,6 +783,7 @@
|
|||||||
/** Native method references. */
|
/** Native method references. */
|
||||||
var ArrayBuffer = context.ArrayBuffer,
|
var ArrayBuffer = context.ArrayBuffer,
|
||||||
clearTimeout = context.clearTimeout,
|
clearTimeout = context.clearTimeout,
|
||||||
|
enumerate = Reflect ? Reflect.enumerate : undefined,
|
||||||
getPrototypeOf = Object.getPrototypeOf,
|
getPrototypeOf = Object.getPrototypeOf,
|
||||||
parseFloat = context.parseFloat,
|
parseFloat = context.parseFloat,
|
||||||
pow = Math.pow,
|
pow = Math.pow,
|
||||||
@@ -1862,29 +1864,6 @@
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The base implementation of `_.iteratee`.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {*} [func=_.identity] The value to convert to an iteratee.
|
|
||||||
* @returns {Function} Returns the iteratee.
|
|
||||||
*/
|
|
||||||
function baseIteratee(func) {
|
|
||||||
var type = typeof func;
|
|
||||||
if (type == 'function') {
|
|
||||||
return func;
|
|
||||||
}
|
|
||||||
if (func == null) {
|
|
||||||
return identity;
|
|
||||||
}
|
|
||||||
if (type == 'object') {
|
|
||||||
return isArray(func)
|
|
||||||
? baseMatchesProperty(func[0], func[1])
|
|
||||||
: baseMatches(func);
|
|
||||||
}
|
|
||||||
return property(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base implementation of `baseForIn` and `baseForOwn` which iterates
|
* The base implementation of `baseForIn` and `baseForOwn` which iterates
|
||||||
* over `object` properties returned by `keysFunc` invoking `iteratee` for
|
* over `object` properties returned by `keysFunc` invoking `iteratee` for
|
||||||
@@ -2145,6 +2124,59 @@
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base implementation of `_.iteratee`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {*} [func=_.identity] The value to convert to an iteratee.
|
||||||
|
* @returns {Function} Returns the iteratee.
|
||||||
|
*/
|
||||||
|
function baseIteratee(func) {
|
||||||
|
var type = typeof func;
|
||||||
|
if (type == 'function') {
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
if (func == null) {
|
||||||
|
return identity;
|
||||||
|
}
|
||||||
|
if (type == 'object') {
|
||||||
|
return isArray(func)
|
||||||
|
? baseMatchesProperty(func[0], func[1])
|
||||||
|
: baseMatches(func);
|
||||||
|
}
|
||||||
|
return property(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base implementation of `_.keysIn` which does not skip the constructor
|
||||||
|
* property of prototypes or treat sparse arrays as dense.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} object The object to query.
|
||||||
|
* @returns {Array} Returns the array of property names.
|
||||||
|
*/
|
||||||
|
function baseKeysIn(object) {
|
||||||
|
var result = [];
|
||||||
|
for (var key in object) {
|
||||||
|
result.push(key);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// An alternative implementation intended for IE < 9 with es6-shim.
|
||||||
|
if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
|
||||||
|
var baseKeysIn = function(object) {
|
||||||
|
var data,
|
||||||
|
iterator = enumerate(object),
|
||||||
|
result = [];
|
||||||
|
|
||||||
|
while (!(data = iterator.next()).done) {
|
||||||
|
result.push(data.value);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base implementation of `_.map` without support for callback shorthands.
|
* The base implementation of `_.map` without support for callback shorthands.
|
||||||
*
|
*
|
||||||
@@ -3768,6 +3800,29 @@
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes an array of property names based on `object`. If `object` is
|
||||||
|
* an array, `arguments` object, or `string` its index keys are returned,
|
||||||
|
* otherwise an empty array is returned.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} object The object to query.
|
||||||
|
* @returns {Array} Returns the initialized array of property names.
|
||||||
|
*/
|
||||||
|
function initKeys(object) {
|
||||||
|
var length = object.length;
|
||||||
|
length = (length && isLength(length) &&
|
||||||
|
(isArray(object) || isArguments(object) || isString(object)) && length) || 0;
|
||||||
|
|
||||||
|
var index = -1,
|
||||||
|
result = Array(length);
|
||||||
|
|
||||||
|
while (++index < length) {
|
||||||
|
result[index] = (index + '');
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes the method at `path` on `object`.
|
* Invokes the method at `path` on `object`.
|
||||||
*
|
*
|
||||||
@@ -3889,6 +3944,20 @@
|
|||||||
return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if `value` is a prototype.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {*} value The value to check.
|
||||||
|
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
|
||||||
|
*/
|
||||||
|
function isPrototype(value) {
|
||||||
|
var Ctor = !!value && value.constructor,
|
||||||
|
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
|
||||||
|
|
||||||
|
return value === proto;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
|
* Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
|
||||||
*
|
*
|
||||||
@@ -8981,23 +9050,19 @@
|
|||||||
*/
|
*/
|
||||||
function keys(object) {
|
function keys(object) {
|
||||||
object = toObject(object);
|
object = toObject(object);
|
||||||
if (!isArrayLike(object)) {
|
|
||||||
|
var isProto = isPrototype(object);
|
||||||
|
if (!(isProto || isArrayLike(object))) {
|
||||||
return nativeKeys(object);
|
return nativeKeys(object);
|
||||||
}
|
}
|
||||||
var length = object.length;
|
var result = initKeys(object),
|
||||||
length = (length && isLength(length) &&
|
length = result.length,
|
||||||
(isArray(object) || isArguments(object) || isString(object)) && length) || 0;
|
skipIndexes = !!length;
|
||||||
|
|
||||||
var index = -1,
|
|
||||||
skipIndexes = length > 0,
|
|
||||||
result = Array(length);
|
|
||||||
|
|
||||||
while (++index < length) {
|
|
||||||
result[index] = (index + '');
|
|
||||||
}
|
|
||||||
for (var key in object) {
|
for (var key in object) {
|
||||||
if (hasOwnProperty.call(object, key) &&
|
if (hasOwnProperty.call(object, key) &&
|
||||||
!(skipIndexes && isIndex(key, length))) {
|
!(skipIndexes && isIndex(key, length)) &&
|
||||||
|
!(isProto && key == 'constructor')) {
|
||||||
result.push(key);
|
result.push(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9029,22 +9094,20 @@
|
|||||||
function keysIn(object) {
|
function keysIn(object) {
|
||||||
object = toObject(object);
|
object = toObject(object);
|
||||||
|
|
||||||
var cache = {},
|
var index = -1,
|
||||||
result = [];
|
isProto = isPrototype(object),
|
||||||
|
props = baseKeysIn(object),
|
||||||
|
propsLength = props.length,
|
||||||
|
result = initKeys(object),
|
||||||
|
length = result.length,
|
||||||
|
skipIndexes = !!length;
|
||||||
|
|
||||||
while (object) {
|
while (++index < propsLength) {
|
||||||
var index = -1,
|
var key = props[index];
|
||||||
props = keys(object),
|
if (!(skipIndexes && isIndex(key, length)) &&
|
||||||
length = props.length;
|
!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
|
||||||
|
result.push(key);
|
||||||
while (++index < length) {
|
|
||||||
var key = props[index];
|
|
||||||
if (cache[key] !== cache) {
|
|
||||||
result.push(key);
|
|
||||||
cache[key] = cache;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
object = getPrototypeOf(object);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user