mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-01 07:47:49 +00:00
Optimize object iteration using Object.keys where faster than for-in loops.
Former-commit-id: 8826f75cf6eaf4233758684e3aae2ccdc3c9f262
This commit is contained in:
@@ -23,11 +23,15 @@
|
||||
'iteratorBind',
|
||||
'length',
|
||||
'methodName',
|
||||
'nativeKeys',
|
||||
'noaccum',
|
||||
'object',
|
||||
'objectTypes',
|
||||
'prop',
|
||||
'propIndex',
|
||||
'props',
|
||||
'property',
|
||||
'propertyIsEnumerable',
|
||||
'result',
|
||||
'skipProto',
|
||||
'slice',
|
||||
@@ -59,7 +63,8 @@
|
||||
'objectBranch',
|
||||
'shadowed',
|
||||
'top',
|
||||
'useHas'
|
||||
'useHas',
|
||||
'useNativeKeys'
|
||||
];
|
||||
|
||||
/** Used to minify variables and string values to a single character */
|
||||
@@ -74,6 +79,7 @@
|
||||
'all',
|
||||
'amd',
|
||||
'any',
|
||||
'attachEvent',
|
||||
'bind',
|
||||
'bindAll',
|
||||
'chain',
|
||||
|
||||
48
lodash.js
48
lodash.js
@@ -131,6 +131,9 @@
|
||||
/* Detect if `Function#bind` exists and is inferred to be fast (i.e. all but V8) */
|
||||
var useNativeBind = nativeBind && /\n|Opera/.test(nativeBind + toString.call(window.opera));
|
||||
|
||||
/* Detect if `Object.keys` exists and is inferred to be fast (i.e. V8, Opera, IE) */
|
||||
var useNativeKeys = nativeKeys && /^.+$|true/.test(nativeKeys + !!window.attachEvent);
|
||||
|
||||
/** Detect if sourceURL syntax is usable without erroring */
|
||||
try {
|
||||
// Adobe's and Narwhal's JS engines will error
|
||||
@@ -279,17 +282,34 @@
|
||||
// the following branch is for iterating an object's own/inherited properties
|
||||
'if (objectBranch) {' +
|
||||
' if (arrayBranch) { %>else {\n<% }' +
|
||||
' if (!hasDontEnumBug) { %> var skipProto = typeof <%= iteratedObject %> == \'function\';\n<% } %>' +
|
||||
' <%= objectBranch.beforeLoop %>;\n' +
|
||||
' if (!hasDontEnumBug) { %>' +
|
||||
' var skipProto = typeof <%= iteratedObject %> == \'function\' && \n' +
|
||||
' propertyIsEnumerable.call(<%= iteratedObject %>, \'prototype\');\n<%' +
|
||||
' } %>' +
|
||||
' <%= objectBranch.beforeLoop %>;\n<%' +
|
||||
|
||||
// iterate own properties using `Object.keys` if it's fast
|
||||
' if (useNativeKeys && useHas) { %>' +
|
||||
' var props = nativeKeys(<%= iteratedObject %>),\n' +
|
||||
' propIndex = -1,\n' +
|
||||
' length = props.length;\n' +
|
||||
' while (++propIndex < length) {\n' +
|
||||
' index = props[propIndex];\n' +
|
||||
' if (!(skipProto && index == \'prototype\')) {\n' +
|
||||
' <%= objectBranch.inLoop %>\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
|
||||
// else using a for-in loop
|
||||
' <% } else { %>' +
|
||||
' for (<%= objectBranch.loopExp %>) {' +
|
||||
' \n<%' +
|
||||
' if (hasDontEnumBug) {' +
|
||||
' if (useHas) { %> if (<%= hasExp %>) {\n <% } %>' +
|
||||
' if (hasDontEnumBug) {' +
|
||||
' if (useHas) { %> if (<%= hasExp %>) {\n <% } %>' +
|
||||
' <%= objectBranch.inLoop %>;<%' +
|
||||
' if (useHas) { %>\n }<% }' +
|
||||
' }' +
|
||||
' else {' +
|
||||
' %>' +
|
||||
' if (useHas) { %>\n }<% }' +
|
||||
' }' +
|
||||
' else { %>' +
|
||||
|
||||
// Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
|
||||
// (if the prototype or a property on the prototype has been set)
|
||||
@@ -300,8 +320,9 @@
|
||||
' if (!(skipProto && index == \'prototype\')<% if (useHas) { %> && <%= hasExp %><% } %>) {\n' +
|
||||
' <%= objectBranch.inLoop %>\n' +
|
||||
' }' +
|
||||
' <% } %>\n' +
|
||||
' <% } %>\n' +
|
||||
' }' +
|
||||
' <% } %>' +
|
||||
|
||||
// Because IE < 9 can't set the `[[Enumerable]]` attribute of an
|
||||
// existing property and the `constructor` property of a prototype
|
||||
@@ -309,7 +330,7 @@
|
||||
// property when it infers it's iterating over a `prototype` object.
|
||||
' <% if (hasDontEnumBug) { %>\n' +
|
||||
' var ctor = <%= iteratedObject %>.constructor;\n' +
|
||||
' <% for (var k = 0; k < 7; k++) { %>\n' +
|
||||
' <% for (var k = 0; k < 7; k++) { %>\n' +
|
||||
' index = \'<%= shadowed[k] %>\';\n' +
|
||||
' if (<%' +
|
||||
' if (shadowed[k] == \'constructor\') {' +
|
||||
@@ -479,6 +500,7 @@
|
||||
|
||||
data.firstArg = firstArg;
|
||||
data.hasDontEnumBug = hasDontEnumBug;
|
||||
data.useNativeKeys = useNativeKeys;
|
||||
data.hasExp = 'hasOwnProperty.call(' + iteratedObject + ', index)';
|
||||
data.iteratedObject = iteratedObject;
|
||||
data.shadowed = shadowed;
|
||||
@@ -496,13 +518,15 @@
|
||||
// create the function factory
|
||||
var factory = Function(
|
||||
'arrayClass, compareAscending, funcClass, hasOwnProperty, identity, ' +
|
||||
'iteratorBind, objectTypes, slice, stringClass, toString',
|
||||
'iteratorBind, objectTypes, nativeKeys, propertyIsEnumerable, ' +
|
||||
'slice, stringClass, toString',
|
||||
'"use strict"; return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
|
||||
);
|
||||
// return the compiled function
|
||||
return factory(
|
||||
arrayClass, compareAscending, funcClass, hasOwnProperty, identity,
|
||||
iteratorBind, objectTypes, slice, stringClass, toString
|
||||
iteratorBind, objectTypes, nativeKeys, propertyIsEnumerable, slice,
|
||||
stringClass, toString
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user