diff --git a/build.js b/build.js index 899d190a8..0f42a66cf 100755 --- a/build.js +++ b/build.js @@ -97,7 +97,7 @@ 'indexOf': ['sortedIndex'], 'initial': [], 'intersection': ['indexOf'], - 'invert': ['forOwn'], + 'invert': ['keys'], 'invoke': ['forEach'], 'isArguments': [], 'isArray': [], @@ -129,7 +129,7 @@ 'object': [], 'omit': ['forIn', 'indexOf'], 'once': [], - 'pairs': ['forOwn'], + 'pairs': ['keys'], 'partial': ['isFunction', 'isObject'], 'pick': ['forIn'], 'pluck': ['map'], @@ -155,7 +155,7 @@ 'uniq': ['identity', 'indexOf'], 'uniqueId': [], 'value': ['mixin'], - 'values': ['forOwn'], + 'values': ['keys'], 'where': ['filter', 'keys'], 'without': ['indexOf'], 'wrap': [], diff --git a/lodash.js b/lodash.js index f4a8bb12d..7e659648c 100644 --- a/lodash.js +++ b/lodash.js @@ -892,6 +892,26 @@ */ var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); + /** + * Creates an array composed of the own enumerable property names of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns a new array of property names. + * @example + * + * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); + * // => ['one', 'two', 'three'] (order is not guaranteed) + */ + var keys = !nativeKeys ? shimKeys : function(object) { + // avoid iterating over the `prototype` property + return typeof object == 'function' && propertyIsEnumerable.call(object, 'prototype') + ? shimKeys(object) + : (isObject(object) ? nativeKeys(object) : []); + }; + /** * A fallback implementation of `isPlainObject` that checks if a given `value` * is an object created by the `Object` constructor, assuming objects created @@ -1179,10 +1199,15 @@ * // => { 'Moe': 'first', 'Larry': 'second', 'Curly': 'third' } (order is not guaranteed) */ function invert(object) { - var result = {}; - forOwn(object, function(value, key) { - result[value] = key; - }); + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + result[object[key]] = key; + } return result; } @@ -1684,26 +1709,6 @@ return typeof value == 'undefined'; } - /** - * Creates an array composed of the own enumerable property names of `object`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns a new array of property names. - * @example - * - * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); - * // => ['one', 'two', 'three'] (order is not guaranteed) - */ - var keys = !nativeKeys ? shimKeys : function(object) { - // avoid iterating over the `prototype` property - return typeof object == 'function' && propertyIsEnumerable.call(object, 'prototype') - ? shimKeys(object) - : (isObject(object) ? nativeKeys(object) : []); - }; - /** * Merges enumerable properties of the source object(s) into the `destination` * object. Subsequent sources will overwrite propery assignments of previous @@ -1844,10 +1849,15 @@ * // => [['moe', 30], ['larry', 40], ['curly', 50]] (order is not guaranteed) */ function pairs(object) { - var result = []; - forOwn(object, function(value, key) { - result.push([key, value]); - }); + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } return result; } @@ -1914,10 +1924,14 @@ * // => [1, 2, 3] */ function values(object) { - var result = []; - forOwn(object, function(value) { - result.push(value); - }); + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } return result; }