mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-07 01:57:50 +00:00
Ensure _.keys use in createIterator is consistent per build.
Former-commit-id: a4e0aef177d4d1c26ed5ce088574b591a6666d0d
This commit is contained in:
314
lodash.js
314
lodash.js
@@ -185,7 +185,6 @@
|
||||
|
||||
/** Detect various environments */
|
||||
var isIeOpera = reNative.test(context.attachEvent),
|
||||
isJSC = !/\n{2,}/.test(Function()),
|
||||
isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
|
||||
|
||||
/** Used to lookup a built-in constructor by [[Class]] */
|
||||
@@ -302,14 +301,6 @@
|
||||
*/
|
||||
support.fastBind = nativeBind && !isV8;
|
||||
|
||||
/**
|
||||
* Detect if `Object.keys` exists and is inferred to be fast (Firefox, IE, Opera, V8).
|
||||
*
|
||||
* @memberOf _.support
|
||||
* @type Boolean
|
||||
*/
|
||||
support.fastKeys = nativeKeys && (isIeOpera || isV8 || !isJSC);
|
||||
|
||||
/**
|
||||
* Detect if own properties are iterated after inherited properties (all but IE < 9).
|
||||
*
|
||||
@@ -452,7 +443,7 @@
|
||||
// the `iterable` may be reassigned by the `top` snippet
|
||||
'var index, iterable = <%= firstArg %>, ' +
|
||||
// assign the `result` variable an initial value
|
||||
'result = iterable;\n' +
|
||||
'result = <%= init %>;\n' +
|
||||
// exit early if the first argument is falsey
|
||||
'if (!iterable) return result;\n' +
|
||||
// add code before the iteration branches
|
||||
@@ -495,9 +486,9 @@
|
||||
' <% } %>' +
|
||||
|
||||
// iterate own properties using `Object.keys` if it's fast
|
||||
' <% if (support.fastKeys && useHas) { %>\n' +
|
||||
' <% if (useHas && useKeys) { %>\n' +
|
||||
' var ownIndex = -1,\n' +
|
||||
' ownProps = objectTypes[typeof iterable] ? nativeKeys(iterable) : [],\n' +
|
||||
' ownProps = objectTypes[typeof iterable] ? keys(iterable) : [],\n' +
|
||||
' length = ownProps.length;\n\n' +
|
||||
' while (++ownIndex < length) {\n' +
|
||||
' index = ownProps[ownIndex];\n' +
|
||||
@@ -727,9 +718,11 @@
|
||||
// iterator options
|
||||
'arrays': 'isArray(iterable)',
|
||||
'bottom': '',
|
||||
'init': 'iterable',
|
||||
'loop': '',
|
||||
'top': '',
|
||||
'useHas': true
|
||||
'useHas': true,
|
||||
'useKeys': !!keys
|
||||
};
|
||||
|
||||
// merge options into a template data object
|
||||
@@ -743,14 +736,14 @@
|
||||
|
||||
// create the function factory
|
||||
var factory = Function(
|
||||
'hasOwnProperty, isArguments, isArray, isString, lodash, ' +
|
||||
'objectTypes, nativeKeys',
|
||||
'hasOwnProperty, isArguments, isArray, isString, keys, ' +
|
||||
'lodash, objectTypes',
|
||||
'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
|
||||
);
|
||||
// return the compiled function
|
||||
return factory(
|
||||
hasOwnProperty, isArguments, isArray, isString, lodash,
|
||||
objectTypes, nativeKeys
|
||||
hasOwnProperty, isArguments, isArray, isString, keys,
|
||||
lodash, objectTypes
|
||||
);
|
||||
}
|
||||
|
||||
@@ -828,6 +821,63 @@
|
||||
// no operation performed
|
||||
}
|
||||
|
||||
/**
|
||||
* A fallback implementation of `isPlainObject` that checks if a given `value`
|
||||
* is an object created by the `Object` constructor, assuming objects created
|
||||
* by the `Object` constructor have no inherited enumerable properties and that
|
||||
* there are no `Object.prototype` extensions.
|
||||
*
|
||||
* @private
|
||||
* @param {Mixed} value The value to check.
|
||||
* @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
|
||||
*/
|
||||
function shimIsPlainObject(value) {
|
||||
// avoid non-objects and false positives for `arguments` objects
|
||||
var result = false;
|
||||
if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) {
|
||||
return result;
|
||||
}
|
||||
// check that the constructor is `Object` (i.e. `Object instanceof Object`)
|
||||
var ctor = value.constructor;
|
||||
if ((!isFunction(ctor) && (support.nodeClass || !isNode(value))) || ctor instanceof ctor) {
|
||||
// IE < 9 iterates inherited properties before own properties. If the first
|
||||
// iterated property is an object's own property then there are no inherited
|
||||
// enumerable properties.
|
||||
if (support.ownLast) {
|
||||
forIn(value, function(value, key, object) {
|
||||
result = hasOwnProperty.call(object, key);
|
||||
return false;
|
||||
});
|
||||
return result === true;
|
||||
}
|
||||
// In most environments an object's own properties are iterated before
|
||||
// its inherited properties. If the last iterated property is an object's
|
||||
// own property then there are no inherited enumerable properties.
|
||||
forIn(value, function(value, key) {
|
||||
result = key;
|
||||
});
|
||||
return result === false || hasOwnProperty.call(value, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* A fallback implementation of `Object.keys` that produces an array of the
|
||||
* given object's own enumerable property names.
|
||||
*
|
||||
* @private
|
||||
* @type Function
|
||||
* @param {Object} object The object to inspect.
|
||||
* @returns {Array} Returns a new array of property names.
|
||||
*/
|
||||
var shimKeys = createIterator({
|
||||
'args': 'object',
|
||||
'init': '[]',
|
||||
'top': 'if (!(objectTypes[typeof object])) return result',
|
||||
'loop': 'result.push(index)',
|
||||
'arrays': false
|
||||
});
|
||||
|
||||
/**
|
||||
* Slices the `collection` from the `start` index up to, but not including,
|
||||
* the `end` index.
|
||||
@@ -895,92 +945,6 @@
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is similar to `_.find`, except that it returns the key of the
|
||||
* element that passes the callback check, instead of the element itself.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @category Objects
|
||||
* @param {Array|Object|String} collection The collection to iterate over.
|
||||
* @param {Function|Object|String} [callback=identity] The function called per
|
||||
* iteration. If a property name or object is passed, it will be used to create
|
||||
* a "_.pluck" or "_.where" style callback, respectively.
|
||||
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
||||
* @returns {Mixed} Returns the key of the found element, else `undefined`.
|
||||
* @example
|
||||
*
|
||||
* _.findKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function(num) { return num % 2 == 0; });
|
||||
* // => 'b'
|
||||
*/
|
||||
function findKey(collection, callback, thisArg) {
|
||||
var result;
|
||||
callback = lodash.createCallback(callback, thisArg);
|
||||
forOwn(collection, function(value, key, collection) {
|
||||
if (callback(value, key, collection)) {
|
||||
result = key;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over `object`'s own and inherited enumerable properties, executing
|
||||
* the `callback` for each property. The `callback` is bound to `thisArg` and
|
||||
* invoked with three arguments; (value, key, object). Callbacks may exit iteration
|
||||
* early by explicitly returning `false`.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @type Function
|
||||
* @category Objects
|
||||
* @param {Object} object The object to iterate over.
|
||||
* @param {Function} [callback=identity] The function called per iteration.
|
||||
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
||||
* @returns {Object} Returns `object`.
|
||||
* @example
|
||||
*
|
||||
* function Dog(name) {
|
||||
* this.name = name;
|
||||
* }
|
||||
*
|
||||
* Dog.prototype.bark = function() {
|
||||
* alert('Woof, woof!');
|
||||
* };
|
||||
*
|
||||
* _.forIn(new Dog('Dagny'), function(value, key) {
|
||||
* alert(key);
|
||||
* });
|
||||
* // => alerts 'name' and 'bark' (order is not guaranteed)
|
||||
*/
|
||||
var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
|
||||
'useHas': false
|
||||
});
|
||||
|
||||
/**
|
||||
* Iterates over an object's own enumerable properties, executing the `callback`
|
||||
* for each property. The `callback` is bound to `thisArg` and invoked with three
|
||||
* arguments; (value, key, object). Callbacks may exit iteration early by explicitly
|
||||
* returning `false`.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @type Function
|
||||
* @category Objects
|
||||
* @param {Object} object The object to iterate over.
|
||||
* @param {Function} [callback=identity] The function called per iteration.
|
||||
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
||||
* @returns {Object} Returns `object`.
|
||||
* @example
|
||||
*
|
||||
* _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
|
||||
* alert(key);
|
||||
* });
|
||||
* // => alerts '0', '1', and 'length' (order is not guaranteed)
|
||||
*/
|
||||
var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
|
||||
|
||||
/**
|
||||
* Checks if `value` is an array.
|
||||
*
|
||||
@@ -1027,62 +991,6 @@
|
||||
return nativeKeys(object);
|
||||
};
|
||||
|
||||
/**
|
||||
* A fallback implementation of `isPlainObject` that checks if a given `value`
|
||||
* is an object created by the `Object` constructor, assuming objects created
|
||||
* by the `Object` constructor have no inherited enumerable properties and that
|
||||
* there are no `Object.prototype` extensions.
|
||||
*
|
||||
* @private
|
||||
* @param {Mixed} value The value to check.
|
||||
* @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
|
||||
*/
|
||||
function shimIsPlainObject(value) {
|
||||
// avoid non-objects and false positives for `arguments` objects
|
||||
var result = false;
|
||||
if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) {
|
||||
return result;
|
||||
}
|
||||
// check that the constructor is `Object` (i.e. `Object instanceof Object`)
|
||||
var ctor = value.constructor;
|
||||
if ((!isFunction(ctor) && (support.nodeClass || !isNode(value))) || ctor instanceof ctor) {
|
||||
// IE < 9 iterates inherited properties before own properties. If the first
|
||||
// iterated property is an object's own property then there are no inherited
|
||||
// enumerable properties.
|
||||
if (support.ownLast) {
|
||||
forIn(value, function(value, key, object) {
|
||||
result = hasOwnProperty.call(object, key);
|
||||
return false;
|
||||
});
|
||||
return result === true;
|
||||
}
|
||||
// In most environments an object's own properties are iterated before
|
||||
// its inherited properties. If the last iterated property is an object's
|
||||
// own property then there are no inherited enumerable properties.
|
||||
forIn(value, function(value, key) {
|
||||
result = key;
|
||||
});
|
||||
return result === false || hasOwnProperty.call(value, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* A fallback implementation of `Object.keys` that produces an array of the
|
||||
* given object's own enumerable property names.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to inspect.
|
||||
* @returns {Array} Returns a new array of property names.
|
||||
*/
|
||||
function shimKeys(object) {
|
||||
var result = [];
|
||||
forOwn(object, function(value, key) {
|
||||
result.push(key);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to convert characters to HTML entities:
|
||||
*
|
||||
@@ -1340,6 +1248,93 @@
|
||||
*/
|
||||
var defaults = createIterator(defaultsIteratorOptions);
|
||||
|
||||
|
||||
/**
|
||||
* This method is similar to `_.find`, except that it returns the key of the
|
||||
* element that passes the callback check, instead of the element itself.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @category Objects
|
||||
* @param {Array|Object|String} collection The collection to iterate over.
|
||||
* @param {Function|Object|String} [callback=identity] The function called per
|
||||
* iteration. If a property name or object is passed, it will be used to create
|
||||
* a "_.pluck" or "_.where" style callback, respectively.
|
||||
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
||||
* @returns {Mixed} Returns the key of the found element, else `undefined`.
|
||||
* @example
|
||||
*
|
||||
* _.findKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function(num) { return num % 2 == 0; });
|
||||
* // => 'b'
|
||||
*/
|
||||
function findKey(collection, callback, thisArg) {
|
||||
var result;
|
||||
callback = lodash.createCallback(callback, thisArg);
|
||||
forOwn(collection, function(value, key, collection) {
|
||||
if (callback(value, key, collection)) {
|
||||
result = key;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over `object`'s own and inherited enumerable properties, executing
|
||||
* the `callback` for each property. The `callback` is bound to `thisArg` and
|
||||
* invoked with three arguments; (value, key, object). Callbacks may exit iteration
|
||||
* early by explicitly returning `false`.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @type Function
|
||||
* @category Objects
|
||||
* @param {Object} object The object to iterate over.
|
||||
* @param {Function} [callback=identity] The function called per iteration.
|
||||
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
||||
* @returns {Object} Returns `object`.
|
||||
* @example
|
||||
*
|
||||
* function Dog(name) {
|
||||
* this.name = name;
|
||||
* }
|
||||
*
|
||||
* Dog.prototype.bark = function() {
|
||||
* alert('Woof, woof!');
|
||||
* };
|
||||
*
|
||||
* _.forIn(new Dog('Dagny'), function(value, key) {
|
||||
* alert(key);
|
||||
* });
|
||||
* // => alerts 'name' and 'bark' (order is not guaranteed)
|
||||
*/
|
||||
var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
|
||||
'useHas': false
|
||||
});
|
||||
|
||||
/**
|
||||
* Iterates over an object's own enumerable properties, executing the `callback`
|
||||
* for each property. The `callback` is bound to `thisArg` and invoked with three
|
||||
* arguments; (value, key, object). Callbacks may exit iteration early by explicitly
|
||||
* returning `false`.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @type Function
|
||||
* @category Objects
|
||||
* @param {Object} object The object to iterate over.
|
||||
* @param {Function} [callback=identity] The function called per iteration.
|
||||
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
||||
* @returns {Object} Returns `object`.
|
||||
* @example
|
||||
*
|
||||
* _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
|
||||
* alert(key);
|
||||
* });
|
||||
* // => alerts '0', '1', and 'length' (order is not guaranteed)
|
||||
*/
|
||||
var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
|
||||
|
||||
/**
|
||||
* Creates a sorted array of all enumerable properties, own and inherited,
|
||||
* of `object` that have function values.
|
||||
@@ -5409,6 +5404,7 @@
|
||||
// add pseudo private property to be used and removed during the build process
|
||||
lodash._each = each;
|
||||
lodash._iteratorTemplate = iteratorTemplate;
|
||||
lodash._shimKeys = shimKeys;
|
||||
|
||||
return lodash;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user