mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-29 06:27:49 +00:00
Optimize _.clone.
This commit is contained in:
114
lodash.js
114
lodash.js
@@ -1353,46 +1353,80 @@
|
|||||||
if (typeof result != 'undefined') {
|
if (typeof result != 'undefined') {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
var isObj = isObject(value);
|
var isArr = isArray(value),
|
||||||
if (isObj) {
|
isShallow = !isDeep;
|
||||||
|
|
||||||
|
if (isArr) {
|
||||||
|
result = isDeep ? value.constructor(value.length) : slice(value);
|
||||||
|
|
||||||
|
// add array properties assigned by `RegExp#exec`
|
||||||
|
if (typeof value[0] == 'string' && hasOwnProperty.call(value, 'index')) {
|
||||||
|
result.index = value.index;
|
||||||
|
result.input = value.input;
|
||||||
|
}
|
||||||
|
if (isShallow) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!isObject(value)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
var className = toString.call(value);
|
var className = toString.call(value);
|
||||||
if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) {
|
if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
var isArgs = className == argsClass || (!support.argsClass && isArguments(value)),
|
||||||
|
isObj = !isArgs && className == objectClass;
|
||||||
|
|
||||||
|
if (isShallow && (isArgs || isObj)) {
|
||||||
|
result = baseAssign({}, value);
|
||||||
|
}
|
||||||
|
if (isShallow && isObj) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
var Ctor = value.constructor;
|
var Ctor = value.constructor;
|
||||||
if (className == objectClass && !(isFunction(Ctor) && (Ctor instanceof Ctor))) {
|
if (className == objectClass && !(isFunction(Ctor) && (Ctor instanceof Ctor))) {
|
||||||
Ctor = Object;
|
Ctor = Object;
|
||||||
}
|
}
|
||||||
switch (className) {
|
if (isDeep && (isArgs || isObj)) {
|
||||||
case arrayBufferClass:
|
result = new Ctor;
|
||||||
return cloneBuffer(value);
|
}
|
||||||
|
else {
|
||||||
case boolClass:
|
switch (className) {
|
||||||
case dateClass:
|
case arrayBufferClass:
|
||||||
return new Ctor(+value);
|
return cloneBuffer(value);
|
||||||
|
|
||||||
case float32Class: case float64Class:
|
case boolClass:
|
||||||
case int8Class: case int16Class: case int32Class:
|
case dateClass:
|
||||||
case uint8Class: case uint8ClampedClass: case uint16Class: case uint32Class:
|
return new Ctor(+value);
|
||||||
// Safari 5 mobile incorrectly has `Object` as the constructor
|
|
||||||
if (Ctor instanceof Ctor) {
|
case float32Class: case float64Class:
|
||||||
Ctor = ctorByClass[className];
|
case int8Class: case int16Class: case int32Class:
|
||||||
}
|
case uint8Class: case uint8ClampedClass: case uint16Class: case uint32Class:
|
||||||
return new Ctor(cloneBuffer(value.buffer));
|
// Safari 5 mobile incorrectly has `Object` as the constructor
|
||||||
|
if (Ctor instanceof Ctor) {
|
||||||
case numberClass:
|
Ctor = ctorByClass[className];
|
||||||
case stringClass:
|
}
|
||||||
return new Ctor(value);
|
return new Ctor(cloneBuffer(value.buffer));
|
||||||
|
|
||||||
case regexpClass:
|
case numberClass:
|
||||||
result = Ctor(value.source, reFlags.exec(value));
|
case stringClass:
|
||||||
result.lastIndex = value.lastIndex;
|
return new Ctor(value);
|
||||||
return result;
|
|
||||||
|
case regexpClass:
|
||||||
|
result = Ctor(value.source, reFlags.exec(value));
|
||||||
|
result.lastIndex = value.lastIndex;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
var isArr = isArray(value);
|
if (isArgs) {
|
||||||
|
result.length = value.length;
|
||||||
|
}
|
||||||
|
if (isShallow) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
if (isDeep) {
|
if (isDeep) {
|
||||||
// check for circular references and return corresponding clone
|
// check for circular references and return corresponding clone
|
||||||
stackA || (stackA = []);
|
stackA || (stackA = []);
|
||||||
@@ -1404,26 +1438,6 @@
|
|||||||
return stackB[length];
|
return stackB[length];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = isArr ? Ctor(value.length) : new Ctor;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = isArr ? slice(value) : baseAssign({}, value);
|
|
||||||
}
|
|
||||||
if (className == argsClass || (!support.argsClass && isArguments(value))) {
|
|
||||||
result.length = value.length;
|
|
||||||
}
|
|
||||||
// add array properties assigned by `RegExp#exec`
|
|
||||||
else if (isArr) {
|
|
||||||
if (hasOwnProperty.call(value, 'index')) {
|
|
||||||
result.index = value.index;
|
|
||||||
}
|
|
||||||
if (hasOwnProperty.call(value, 'input')) {
|
|
||||||
result.input = value.input;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// exit for shallow clone
|
|
||||||
if (!isDeep) {
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
// add the source value to the stack of traversed objects
|
// add the source value to the stack of traversed objects
|
||||||
// and associate it with its clone
|
// and associate it with its clone
|
||||||
|
|||||||
10
perf/perf.js
10
perf/perf.js
@@ -655,6 +655,16 @@
|
|||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
suites.push(
|
||||||
|
Benchmark.Suite('`_.clone` with an array')
|
||||||
|
.add(buildName, '\
|
||||||
|
lodash.clone(numbers)'
|
||||||
|
)
|
||||||
|
.add(otherName, '\
|
||||||
|
_.clone(numbers)'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
suites.push(
|
suites.push(
|
||||||
Benchmark.Suite('`_.clone` with an object')
|
Benchmark.Suite('`_.clone` with an object')
|
||||||
.add(buildName, '\
|
.add(buildName, '\
|
||||||
|
|||||||
Reference in New Issue
Block a user