mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-31 15:27:50 +00:00
Reduce temporary objects created in _.merge, _.clone, and _.isEqual.
Former-commit-id: e6696642505f39eefdf59075ff8a993ab033465a
This commit is contained in:
@@ -44,7 +44,7 @@
|
||||
'callee',
|
||||
'className',
|
||||
'compareAscending',
|
||||
'destValue',
|
||||
'data',
|
||||
'forIn',
|
||||
'found',
|
||||
'funcs',
|
||||
@@ -66,10 +66,11 @@
|
||||
'propsLength',
|
||||
'recursive',
|
||||
'source',
|
||||
'stack',
|
||||
'sources',
|
||||
'stackLength',
|
||||
'target',
|
||||
'valueProp'
|
||||
'valueProp',
|
||||
'values'
|
||||
];
|
||||
|
||||
/** Used to minify `compileIterator` option properties */
|
||||
@@ -107,18 +108,17 @@
|
||||
'__chain__',
|
||||
'__proto__',
|
||||
'__wrapped__',
|
||||
'a',
|
||||
'after',
|
||||
'all',
|
||||
'amd',
|
||||
'any',
|
||||
'attachEvent',
|
||||
'b',
|
||||
'bind',
|
||||
'bindAll',
|
||||
'chain',
|
||||
'clearTimeout',
|
||||
'clone',
|
||||
'clones',
|
||||
'collect',
|
||||
'compact',
|
||||
'compose',
|
||||
@@ -214,6 +214,9 @@
|
||||
'sortBy',
|
||||
'sortedIndex',
|
||||
'source',
|
||||
'sources',
|
||||
'stackA',
|
||||
'stackB',
|
||||
'tail',
|
||||
'take',
|
||||
'tap',
|
||||
@@ -304,7 +307,7 @@
|
||||
|
||||
// minify internal properties used by 'compareAscending', `_.clone`, `_.isEqual`, `_.merge`, and `_.sortBy`
|
||||
(function() {
|
||||
var properties = ['criteria', 'index', 'source', 'thorough', 'value'],
|
||||
var properties = ['clones', 'criteria', 'index', 'sources', 'thorough', 'value', 'values'],
|
||||
snippets = source.match(/( +)(?:function (?:clone|compareAscending|isEqual)|var merge|var sortBy)\b[\s\S]+?\n\1}/g);
|
||||
|
||||
if (!snippets) {
|
||||
@@ -319,7 +322,7 @@
|
||||
properties.forEach(function(property, index) {
|
||||
var reBracketProp = RegExp("\\['(" + property + ")'\\]", 'g'),
|
||||
reDotProp = RegExp('\\.' + property + '\\b', 'g'),
|
||||
rePropColon = RegExp("(')?\\b" + property + "\\1 *:", 'g');
|
||||
rePropColon = RegExp("([^?])(')?\\b" + property + "\\2 *:", 'g');
|
||||
|
||||
if (isCompilable) {
|
||||
// add quotes around properties in the inlined `_.merge` and `_.sortBy`
|
||||
@@ -328,20 +331,20 @@
|
||||
modified = modified
|
||||
.replace(reBracketProp, "['" + minNames[index] + "']")
|
||||
.replace(reDotProp, "['" + minNames[index] + "']")
|
||||
.replace(rePropColon, "'" + minNames[index] + "':");
|
||||
.replace(rePropColon, "$1'" + minNames[index] + "':");
|
||||
}
|
||||
else {
|
||||
modified = modified
|
||||
.replace(reBracketProp, '.' + minNames[index])
|
||||
.replace(reDotProp, '.' + minNames[index])
|
||||
.replace(rePropColon, minNames[index] + ':');
|
||||
.replace(rePropColon, '$1' + minNames[index] + ':');
|
||||
}
|
||||
}
|
||||
else {
|
||||
modified = modified
|
||||
.replace(reBracketProp, "['" + minNames[index] + "']")
|
||||
.replace(reDotProp, '.' + minNames[index])
|
||||
.replace(rePropColon, "'" + minNames[index] + "':")
|
||||
.replace(rePropColon, "$1'" + minNames[index] + "':")
|
||||
|
||||
// correct `value.source` in regexp branch of `_.clone`
|
||||
if (property == 'source') {
|
||||
|
||||
52
lodash.js
52
lodash.js
@@ -1141,13 +1141,14 @@
|
||||
return ctor(value.source, reFlags.exec(value));
|
||||
}
|
||||
|
||||
var stack = data.stack || (data.stack = []),
|
||||
length = stack.length;
|
||||
var clones = data.clones || (data.clones = []),
|
||||
sources = data.sources || (data.sources = []),
|
||||
length = clones.length;
|
||||
|
||||
// check for circular references and return corresponding clone
|
||||
while (length--) {
|
||||
if (stack[length].source == value) {
|
||||
return stack[length].value;
|
||||
if (sources[length] == value) {
|
||||
return clones[length];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1155,7 +1156,8 @@
|
||||
var result = isArr ? ctor(length = value.length) : {};
|
||||
|
||||
// add current clone and original source value to the stack of traversed objects
|
||||
stack.push({ 'value': result, 'source': value });
|
||||
clones.push(result);
|
||||
sources.push(value);
|
||||
|
||||
// recursively populate clone (susceptible to call stack limits)
|
||||
if (isArr) {
|
||||
@@ -1512,12 +1514,13 @@
|
||||
// assume cyclic structures are equal
|
||||
// the algorithm for detecting cyclic structures is adapted from ES 5.1
|
||||
// section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3)
|
||||
var stack = data.stack || (data.stack = []),
|
||||
length = stack.length;
|
||||
var stackA = data.stackA || (data.stackA = []),
|
||||
stackB = data.stackB || (data.stackB = []),
|
||||
length = stackA.length;
|
||||
|
||||
while (length--) {
|
||||
if (stack[length].a == a) {
|
||||
return stack[length].b == b;
|
||||
if (stackA[length] == a) {
|
||||
return stackA[length] == b;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1526,7 +1529,8 @@
|
||||
size = 0;
|
||||
|
||||
// add `a` and `b` to the stack of traversed objects
|
||||
stack.push({ 'a': a, 'b': b });
|
||||
stackA.push(a);
|
||||
stackB.push(b);
|
||||
|
||||
// recursively compare objects and arrays (susceptible to call stack limits)
|
||||
if (isArr) {
|
||||
@@ -1800,7 +1804,7 @@
|
||||
* @param {Object} [source1, source2, ...] The source objects.
|
||||
* @param {Object} [indicator] Internally used to indicate that the `stack`
|
||||
* argument is an array of traversed objects instead of another source object.
|
||||
* @param {Array} [stack=[]] Internally used to track traversed objects to avoid
|
||||
* @param {Object} [data={}] Internally used to track traversed objects to avoid
|
||||
* circular references.
|
||||
* @returns {Object} Returns the destination object.
|
||||
* @example
|
||||
@@ -1821,26 +1825,28 @@
|
||||
var merge = createIterator(extendIteratorOptions, {
|
||||
'args': 'object, source, indicator',
|
||||
'top':
|
||||
'var isArr, recursive = indicator == isPlainObject, stack = recursive ? arguments[3] : [];\n' +
|
||||
'var isArr, source, recursive = indicator == isPlainObject,\n' +
|
||||
' data = recursive ? arguments[3] : { values: [], sources: [] };\n' +
|
||||
'for (var argsIndex = 1, argsLength = recursive ? 2 : arguments.length; argsIndex < argsLength; argsIndex++) {\n' +
|
||||
' if (iteratee = arguments[argsIndex]) {',
|
||||
'inLoop':
|
||||
'if (value && ((isArr = isArray(value)) || isPlainObject(value))) {\n' +
|
||||
' var found = false, stackLength = stack.length;\n' +
|
||||
'if ((source = value) && ((isArr = isArray(source)) || isPlainObject(source))) {\n' +
|
||||
' var found = false, values = data.values, sources = data.sources, stackLength = sources.length;\n' +
|
||||
' while (stackLength--) {\n' +
|
||||
' if (found = stack[stackLength].source == value) break\n' +
|
||||
' if (found = sources[stackLength] == source) break\n' +
|
||||
' }\n' +
|
||||
' if (found) {\n' +
|
||||
' result[index] = stack[stackLength].value\n' +
|
||||
' result[index] = values[stackLength]\n' +
|
||||
' } else {\n' +
|
||||
' var destValue = (destValue = result[index]) && isArr\n' +
|
||||
' ? (isArray(destValue) ? destValue : [])\n' +
|
||||
' : (isPlainObject(destValue) ? destValue : {});\n' +
|
||||
' stack.push({ value: destValue, source: value });\n' +
|
||||
' result[index] = callee(destValue, value, isPlainObject, stack)\n' +
|
||||
' sources.push(source);\n' +
|
||||
' values.push(value = (value = result[index]) && isArr\n' +
|
||||
' ? (isArray(value) ? value : [])\n' +
|
||||
' : (isPlainObject(value) ? value : {})\n' +
|
||||
' );\n' +
|
||||
' result[index] = callee(value, source, isPlainObject, data)\n' +
|
||||
' }\n' +
|
||||
'} else if (value != null) {\n' +
|
||||
' result[index] = value\n' +
|
||||
'} else if (source != null) {\n' +
|
||||
' result[index] = source\n' +
|
||||
'}'
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user