node-v8-clone
Advanced tools
Comparing version 0.2.1 to 0.3.0
var Benchmark = require('benchmark'); | ||
var assert = require('assert'); | ||
try { _ = require('lodash'); } catch (e) {}; | ||
try { lodash = require('lodash'); } catch (e) {}; | ||
try { _ = require('underscore'); } catch (e) {}; | ||
@@ -15,9 +16,5 @@ // array of 5 numeric elements | ||
// node-v8-clone js | ||
clone = require('..').clone; | ||
assert.deepEqual(arr1, clone(arr1)); | ||
var Cloner = require('..').Cloner; | ||
cloner = new Cloner(false); | ||
// node-v8-clone | ||
v8_clone = require('..').v8_clone; | ||
assert.deepEqual(arr1, v8_clone(arr1)); | ||
// array 'for (var i = 0; i < l; i++)' cloner | ||
@@ -52,5 +49,5 @@ arr_for = function(arr) { var result = []; for (var i = 0, l = arr.length; i < l; i++) result.push(arr[i]); return result; } | ||
suite.add('arr1 for in hasOwnProperty ', 'arr_for_in_has(arr1)'); | ||
suite.add('arr1 lodash _.clone ', '_.clone(arr1, false)'); | ||
suite.add('arr1 node-v8-clone js cloner', 'clone(arr1, false)'); | ||
suite.add('arr1 node-v8-clone cloner ', 'v8_clone(arr1)'); | ||
suite.add('arr1 lodash.clone ', 'lodash.clone(arr1, false)'); | ||
suite.add('arr1 _.clone ', '_.clone(arr1)'); | ||
suite.add('arr1 node-v8-clone cloner ', 'cloner.clone(arr1)'); | ||
@@ -62,6 +59,6 @@ suite.add('arr2 slice() ', 'arr2.slice()'); | ||
suite.add('arr2 for in hasOwnProperty ', 'arr_for_in_has(arr2)'); | ||
suite.add('arr2 lodash _.clone ', '_.clone(arr2, false)'); | ||
suite.add('arr2 node-v8-clone js cloner', 'clone(arr2, false)'); | ||
suite.add('arr2 node-v8-clone cloner ', 'v8_clone(arr2)'); | ||
suite.add('arr2 lodash.clone ', 'lodash.clone(arr2, false)'); | ||
suite.add('arr2 _.clone ', '_.clone(arr2)'); | ||
suite.add('arr2 node-v8-clone cloner ', 'cloner.clone(arr2)'); | ||
suite.run({ 'async': true }); |
@@ -20,10 +20,5 @@ var Benchmark = require('benchmark'); | ||
// node-v8-clone js | ||
clone = require('..').clone; | ||
assert.deepEqual(inst, clone(inst)); | ||
var Cloner = require('..').Cloner; | ||
cloner = new Cloner(false); | ||
// node-v8-clone | ||
v8_clone = require('..').v8_clone; | ||
assert.deepEqual(inst, v8_clone(inst)); | ||
var inst2 = clone(inst); | ||
@@ -45,7 +40,6 @@ inst2.constructor(5, 6, 7 ,8) | ||
suite.add('Clazz new Clazz(5, 6, 7, 8) ', 'var inst2 = new Clazz(1, 2, 3, 4);'); | ||
suite.add('Clazz lodash _.clone ', 'var inst2 = _.clone(inst, false);'); | ||
suite.add('Clazz node-v8-clone js cloner', 'var inst2 = clone(inst, false);'); | ||
suite.add('Clazz node-v8-clone cloner ', 'var inst2 = v8_clone(inst);'); | ||
suite.add('Clazz new Clazz(5, 6, 7, 8)', 'var inst2 = new Clazz(1, 2, 3, 4);'); | ||
suite.add('Clazz lodash _.clone ', 'var inst2 = _.clone(inst, false);'); | ||
suite.add('Clazz node-v8-clone cloner ', 'var inst2 = cloner.clone(inst);'); | ||
suite.run({ 'async': true }); |
@@ -9,4 +9,5 @@ var Benchmark = require('benchmark'); | ||
// node-v8-clone | ||
clone = require('..').clone; | ||
assert.deepEqual(date, clone(date)); | ||
var Cloner = require('..').Cloner; | ||
cloner = new Cloner(false); | ||
assert.deepEqual(date, cloner.clone(date)); | ||
@@ -27,4 +28,4 @@ // date 'new Date(date)' cloner | ||
suite.add('date lodash _.clone ', '_.clone(date, false)'); | ||
suite.add('date node-v8-clone cloner ', 'clone(date)'); | ||
suite.add('date node-v8-clone cloner ', 'cloner.clone(date)'); | ||
suite.run({ 'async': true }); |
var Benchmark = require('benchmark'); | ||
var assert = require('assert'); | ||
try { _ = require('lodash'); } catch (e) {}; | ||
try { _ = require('lodash'); } catch (e) { console.warn('lodash module is not installed'); }; | ||
try { clone = require('clone'); } catch(e) { console.warn('clone module is not installed'); }; | ||
try { cloneextend = require('cloneextend'); } catch(e) { console.warn('cloneextend module is not installed'); }; | ||
@@ -20,9 +22,7 @@ // deeparr1: 5 string keys and values | ||
// node-v8-clone js | ||
clone = require('..').clone; | ||
assert.deepEqual(deeparr1, clone(deeparr1)); | ||
// node-v8-clone | ||
v8_deepclone = require('..').v8_deepclone; | ||
assert.deepEqual(deeparr1, v8_deepclone(deeparr1)); | ||
var Cloner = require('..').Cloner; | ||
cloner1 = new Cloner(true); | ||
cloner2 = new Cloner(true, true, { 'Array': Cloner.deep_array }); | ||
cloner3 = new Cloner(true, false, { 'Array': Cloner.deep_array }); | ||
@@ -38,9 +38,15 @@ var suite = new Benchmark.Suite; | ||
suite.add('deeparr1 lodash _.clone ', '_.clone(deeparr1, true)'); | ||
suite.add('deeparr1 node-v8-clone js cloner ', 'clone(deeparr1, true)'); | ||
suite.add('deeparr1 node-v8-clone cloner ', 'v8_deepclone(deeparr1)'); | ||
suite.add('deeparr1 clone ', 'clone(deeparr1)'); | ||
suite.add('deeparr1 cloneextend.clone ', 'cloneextend.clone(deeparr1)'); | ||
suite.add('deeparr1 cloner1 ', 'cloner1.clone(deeparr1)'); | ||
suite.add('deeparr1 cloner2 ', 'cloner2.clone(deeparr1)'); | ||
suite.add('deeparr1 cloner3 ', 'cloner3.clone(deeparr1)'); | ||
suite.add('deeparr2 lodash _.clone ', '_.clone(deeparr2, true)'); | ||
suite.add('deeparr2 node-v8-clone js cloner ', 'clone(deeparr2, true)'); | ||
suite.add('deeparr2 node-v8-clone cloner ', 'v8_deepclone(deeparr2)'); | ||
suite.add('deeparr2 clone ', 'clone(deeparr2)'); | ||
suite.add('deeparr2 cloneextend.clone ', 'cloneextend.clone(deeparr2)'); | ||
suite.add('deeparr2 cloner1 ', 'cloner1.clone(deeparr2)'); | ||
suite.add('deeparr2 cloner2 ', 'cloner2.clone(deeparr2)'); | ||
suite.add('deeparr2 cloner3 ', 'cloner3.clone(deeparr2)'); | ||
suite.run({ 'async': true }); |
var Benchmark = require('benchmark'); | ||
var assert = require('assert'); | ||
try { _ = require('lodash'); } catch (e) {}; | ||
try { _ = require('lodash'); } catch (e) { console.warn('lodash module is not installed'); }; | ||
try { clone = require('clone'); } catch(e) { console.warn('clone module is not installed'); }; | ||
try { cloneextend = require('cloneextend'); } catch(e) { console.warn('cloneextend module is not installed'); }; | ||
@@ -35,10 +37,6 @@ // deep1: 5 sting keys and values | ||
// node-v8-clone js | ||
clone = require('..').clone; | ||
assert.deepEqual(deep1, clone(deep1)); | ||
// cloner | ||
var Cloner = require('..').Cloner; | ||
cloner = new Cloner(true); | ||
// node-v8-clone | ||
v8_deepclone = require('..').v8_deepclone; | ||
assert.deepEqual(deep1, v8_deepclone(deep1)); | ||
var suite = new Benchmark.Suite; | ||
@@ -53,18 +51,21 @@ suite.on('cycle', function(event) { | ||
suite.add('deep1 lodash _.clone ', '_.clone(deep1, true)'); | ||
suite.add('deep1 node-v8-clone js cloner ', 'clone(deep1, true)'); | ||
suite.add('deep1 node-v8-clone cloner ', 'v8_deepclone(deep1)'); | ||
suite.add('deep1 clone ', 'clone(deep1)'); | ||
suite.add('deep1 cloneextend.clone ', 'cloneextend.clone(deep1)'); | ||
suite.add('deep1 node-v8-clone cloner ', 'cloner.clone(deep1)'); | ||
suite.add('deep2 lodash _.clone ', '_.clone(deep2, true)'); | ||
suite.add('deep2 node-v8-clone js cloner ', 'clone(deep2, true)'); | ||
suite.add('deep2 node-v8-clone cloner ', 'v8_deepclone(deep2)'); | ||
suite.add('deep2 clone ', 'clone(deep2)'); | ||
suite.add('deep2 cloneextend.clone ', 'cloneextend.clone(deep2)'); | ||
suite.add('deep2 node-v8-clone cloner ', 'cloner.clone(deep2)'); | ||
suite.add('deep3 lodash _.clone ', '_.clone(deep3, true)'); | ||
suite.add('deep3 node-v8-clone js cloner ', 'clone(deep3, true)'); | ||
suite.add('deep3 node-v8-clone cloner ', 'v8_deepclone(deep3)'); | ||
suite.add('deep3 clone ', 'clone(deep3)'); | ||
suite.add('deep3 cloneextend.clone ', 'cloneextend.clone(deep3)'); | ||
suite.add('deep3 node-v8-clone cloner ', 'cloner.clone(deep3)'); | ||
suite.add('deep4 lodash _.clone ', '_.clone(deep4, true)'); | ||
suite.add('deep4 node-v8-clone js cloner ', 'clone(deep4, true)'); | ||
suite.add('deep4 node-v8-clone cloner ', 'v8_deepclone(deep4)'); | ||
suite.add('deep4 clone ', 'clone(deep4)'); | ||
suite.add('deep4 cloneextend.clone ', 'cloneextend.clone(deep4)'); | ||
suite.add('deep4 node-v8-clone cloner ', 'cloner.clone(deep4)'); | ||
suite.run({ 'async': true }); |
var Benchmark = require('benchmark'); | ||
var assert = require('assert'); | ||
try { _ = require('lodash'); } catch (e) {}; | ||
try { lodash = require('lodash'); } catch (e) {}; | ||
try { _ = require('underscore'); } catch (e) {}; | ||
@@ -29,10 +30,2 @@ // obj1: 5 sting keys and values | ||
// node-v8-clone js | ||
clone = require('..').clone; | ||
assert.deepEqual(obj1, clone(obj1)); | ||
// node-v8-clone | ||
v8_clone = require('..').v8_clone; | ||
assert.deepEqual(obj1, v8_clone(obj1)); | ||
// regular for(var i in obj) cloner | ||
@@ -46,2 +39,6 @@ regular = function(obj) { var result = {}; for(var i in obj) result[i] = obj[i]; return result; }; | ||
// regular cloner with own checks | ||
regular_keys = function(obj) { var result = {}; var props = Object.keys(obj); for(var i = 0, l = props.length; i < l; i++) result[i] = obj[i]; return result; }; | ||
assert.deepEqual(obj1, regular_own(obj1)); | ||
// static cloner | ||
@@ -62,2 +59,5 @@ function createStatic(obj) { | ||
var Cloner = require('..').Cloner; | ||
cloner = new Cloner(false); | ||
var suite = new Benchmark.Suite; | ||
@@ -73,28 +73,32 @@ suite.on('cycle', function(event) { | ||
suite.add('obj1 for in hasOwnProperty ', 'regular_own(obj1)'); | ||
suite.add('obj1 for Object.keys ', 'regular_keys(obj1)'); | ||
suite.add('obj1 static cloner ', 'static1(obj1)'); | ||
suite.add('obj1 lodash _.clone ', '_.clone(obj1, false)'); | ||
suite.add('obj1 node-v8-clone js cloner ', 'clone(obj1, false)'); | ||
suite.add('obj1 node-v8-clone cloner ', 'v8_clone(obj1, false)'); | ||
suite.add('obj1 lodash.clone ', 'lodash.clone(obj1, false)'); | ||
suite.add('obj1 _.clone ', '_.clone(obj1)'); | ||
suite.add('obj1 node-v8-clone cloner ', 'cloner.clone(obj1)'); | ||
suite.add('obj2 for in ', 'regular(obj2)'); | ||
suite.add('obj2 for in hasOwnProperty ', 'regular_own(obj2)'); | ||
suite.add('obj2 for Object.keys ', 'regular_keys(obj2)'); | ||
suite.add('obj2 static cloner ', 'static2(obj2)'); | ||
suite.add('obj2 lodash _.clone ', '_.clone(obj2, false)'); | ||
suite.add('obj2 node-v8-clone js cloner ', 'clone(obj2, false)'); | ||
suite.add('obj2 node-v8-clone cloner ', 'v8_clone(obj2, false)'); | ||
suite.add('obj2 lodash.clone ', 'lodash.clone(obj2, false)'); | ||
suite.add('obj2 _.clone ', '_.clone(obj2)'); | ||
suite.add('obj2 node-v8-clone cloner ', 'cloner.clone(obj2)'); | ||
suite.add('obj3 for in ', 'regular(obj3)'); | ||
suite.add('obj3 for in hasOwnProperty ', 'regular_own(obj3)'); | ||
suite.add('obj3 for Object.keys ', 'regular_keys(obj3)'); | ||
suite.add('obj3 static cloner ', 'static3(obj3)'); | ||
suite.add('obj3 lodash _.clone ', '_.clone(obj3, false)'); | ||
suite.add('obj3 node-v8-clone js cloner ', 'clone(obj3, false)'); | ||
suite.add('obj3 node-v8-clone cloner ', 'v8_clone(obj3, false)'); | ||
suite.add('obj3 lodash.clone ', 'lodash.clone(obj3, false)'); | ||
suite.add('obj3 _.clone ', '_.clone(obj3)'); | ||
suite.add('obj3 node-v8-clone cloner ', 'cloner.clone(obj3)'); | ||
suite.add('obj4 for in ', 'regular(obj4)'); | ||
suite.add('obj4 for in hasOwnProperty ', 'regular_own(obj4)'); | ||
suite.add('obj4 for Object.keys ', 'regular_keys(obj4)'); | ||
suite.add('obj4 static cloner ', 'static4(obj4)'); | ||
suite.add('obj4 lodash _.clone ', '_.clone(obj4, false)'); | ||
suite.add('obj4 node-v8-clone js cloner ', 'clone(obj4, false)'); | ||
suite.add('obj4 node-v8-clone cloner ', 'v8_clone(obj4, false)'); | ||
suite.add('obj4 lodash.clone ', 'lodash.clone(obj4, false)'); | ||
suite.add('obj4 _.clone ', '_.clone(obj4)'); | ||
suite.add('obj4 node-v8-clone cloner ', 'cloner.clone(obj4)'); | ||
suite.run({ 'async': true }); |
114
lib/clone.js
@@ -5,12 +5,60 @@ "use strict"; | ||
var v8_clone = v8_clone_mod.clone; | ||
var v8_deepclone = v8_clone_mod.deepclone; | ||
var lodash = require('lodash'); | ||
var forOwn = lodash.forOwn; | ||
var forEach = lodash.forEach; | ||
var Cloner = module.exports.Cloner = function (deep, circular, map) { | ||
this._deep = !!deep; | ||
this._circular = (typeof circular === 'undefined') ? true : !!circular; | ||
if (!this._circular) { | ||
this.checkCircular = function() {}; | ||
this.addCircular = function() {}; | ||
} | ||
this._map = {}; | ||
if (typeof map === 'object') { | ||
for (var clazz in map) if (map.hasOwnProperty(clazz)) { | ||
this._map[clazz] = this.getStrategy(map[clazz]); | ||
} | ||
} | ||
}; | ||
module.exports.v8_clone = v8_clone; | ||
module.exports.v8_deepclone = v8_deepclone; | ||
/** | ||
* @see Cloner._noop | ||
*/ | ||
Cloner.shallow = Cloner.prototype.shallow = 0; | ||
module.exports.clone = function clone(value, deep, guard, stackA, stackB) { | ||
/** | ||
* @see Cloner._deepCloneObjectProperties | ||
*/ | ||
Cloner.deep = Cloner.prototype.deep = 1; | ||
/** | ||
* @see Cloner._deepCloneArrayValues | ||
*/ | ||
Cloner.deep_array = Cloner.prototype.deep_array = 2; | ||
Cloner.prototype.getStrategy = function(flag) { | ||
if (flag === this.shallow) return this._noop; | ||
if (flag === this.deep) return this._deepCloneObjectProperties; | ||
if (flag === this.deep_array) return this._deepCloneArrayValues; | ||
throw new Error('Unknown strategy'); | ||
}; | ||
Cloner.prototype.clone = function(value) { | ||
if (this._circular) { | ||
this.stackA = []; | ||
this.stackB = []; | ||
} | ||
return this._clone(value); | ||
}; | ||
Cloner.prototype.checkCircular = function(value) { | ||
var pos = this.stackA.indexOf(value); | ||
if (pos !== -1) { | ||
return this.stackB[pos]; | ||
} | ||
return null; | ||
}; | ||
Cloner.prototype.addCircular = function(value, result) { | ||
this.stackA.push(value); | ||
this.stackB.push(result); | ||
}; | ||
Cloner.prototype._clone = function(value) { | ||
// based on type | ||
@@ -21,8 +69,4 @@ if ((value === null) || (typeof value !== 'object' && typeof value !== 'function')) { | ||
if (guard) { | ||
deep = false; | ||
} | ||
// shallow clone | ||
if (!deep) { | ||
if (!this._deep) { | ||
return v8_clone(value); | ||
@@ -32,27 +76,37 @@ } | ||
// check for circular references and return corresponding clone | ||
stackA || (stackA = []); | ||
stackB || (stackB = []); | ||
var result = this.checkCircular(value); | ||
if (result) return result; | ||
var length = stackA.length; | ||
while (length--) { | ||
if (stackA[length] == value) { | ||
return stackB[length]; | ||
} | ||
} | ||
// init cloned object | ||
var result = v8_clone(value); | ||
result = v8_clone(value); | ||
// add the source value to the stack of traversed objects | ||
// and associate it with its clone | ||
stackA.push(value); | ||
stackB.push(result); | ||
this.addCircular(value, result); | ||
var isArr = (value.constructor === Array); | ||
// recursively populate clone (susceptible to call stack limits) | ||
(isArr ? forEach : forOwn)(result, function (objValue, key) { | ||
result[key] = clone(objValue, deep, null, stackA, stackB); | ||
}); | ||
var f = this._map[value.constructor.name] || this._deepCloneObjectProperties; | ||
f(this, result); | ||
return result; | ||
}; | ||
Cloner.prototype._deepCloneObjectProperties = function(cloner, value) { | ||
var props = Object.keys(value); | ||
for (var i = 0, l = props.length; i < l; i++) | ||
if (typeof value[props[i]] === 'object') | ||
value[props[i]] = cloner._clone(value[props[i]]); | ||
}; | ||
Cloner.prototype._deepCloneArrayValues = function(cloner, value) { | ||
for (var i = 0, l = value.length; i < l; i++) | ||
if (typeof value === 'object' || typeof value === 'function') | ||
value[i] = cloner._clone(value[i]); | ||
}; | ||
Cloner.prototype._noop = function(cloner, value) {}; | ||
return result; | ||
var cloner_shallow = new Cloner(); | ||
var cloner_deep = new Cloner(true); | ||
module.exports.clone = function clone(value, deep) { | ||
if (deep) { | ||
return cloner_deep.clone(value); | ||
} | ||
return cloner_shallow.clone(value); | ||
}; |
{ | ||
"name": "node-v8-clone", | ||
"version": "0.2.1", | ||
"description": "UNSTABLE yet. Exposed v8 clone function for node.js.", | ||
"version": "0.3.0", | ||
"description": "The most convenient and accurate cloner for node.js. It's also very fast in some cases (benchmarks inside).", | ||
"main": "lib/clone.js", | ||
"scripts": { | ||
"test": "node_modules/.bin/mocha", | ||
"test": "node_modules/.bin/mocha -R spec test/test.js", | ||
"benchmark": "node bench/arrays.js; node bench/class.js; node bench/date.js; node bench/deep.js; node bench/deep_array.js; node bench/number.js; node bench/object.js; node bench/regexp.js", | ||
@@ -17,3 +17,5 @@ "install": "node-gyp rebuild" | ||
"v8", | ||
"clone" | ||
"clone", | ||
"performance", | ||
"speed" | ||
], | ||
@@ -25,8 +27,10 @@ "author": "Alexey Kupershtokh <alexey.kupershtokh@gmail.com>", | ||
"dependencies": { | ||
"lodash": "*" | ||
}, | ||
"devDependencies": { | ||
"benchmark": "~1.0.0", | ||
"mocha": "~1.7.0" | ||
"mocha": "~1.7.0", | ||
"cloneextend": "*", | ||
"clone": "*", | ||
"lodash": "*" | ||
} | ||
} |
@@ -11,2 +11,3 @@ node-v8-clone | ||
Tested on node.js versions 0.4, 0.6. 0.8 and 0.9. | ||
You may be asked to install `make` and `g++` as well. | ||
``` | ||
@@ -29,3 +30,3 @@ npm install node-v8-clone | ||
// shallow clone | ||
c = clone(a, false); | ||
var c = clone(a, false); | ||
a === c // false | ||
@@ -41,24 +42,29 @@ a.x === c.x // true | ||
obj1 = {a: 'a', b: 'b', c: 'c', d: 'd', e: 'e'} | ||
obj1 for in x 810,922 ops/sec ±1.31% (88 runs sampled) | ||
obj1 for in hasOwnProperty x 572,086 ops/sec ±0.94% (91 runs sampled) | ||
obj1 lodash _.clone x 364,218 ops/sec ±0.91% (89 runs sampled) | ||
obj1 node-v8-clone js cloner x 5,230,347 ops/sec ±2.01% (91 runs sampled) | ||
obj1 for in x 828,849 ops/sec ±0.45% (97 runs sampled) | ||
obj1 for in hasOwnProperty x 584,575 ops/sec ±1.12% (92 runs sampled) | ||
obj1 for Object.keys x 1,074,931 ops/sec ±0.46% (100 runs sampled) | ||
obj1 lodash _.clone x 383,463 ops/sec ±0.68% (94 runs sampled) | ||
obj1 node-v8-clone cloner x 5,503,537 ops/sec ±0.61% (93 runs sampled) | ||
obj2 = {1: 1, 2: 2, 3: 3, 4: 4, 5: 5} | ||
obj2 for in x 493,469 ops/sec ±1.79% (86 runs sampled) | ||
obj2 for in hasOwnProperty x 385,693 ops/sec ±1.53% (86 runs sampled) | ||
obj2 lodash _.clone x 400,466 ops/sec ±2.88% (92 runs sampled) | ||
obj2 node-v8-clone js cloner x 3,676,889 ops/sec ±2.58% (88 runs sampled) | ||
obj2 for in x 553,909 ops/sec ±0.63% (90 runs sampled) | ||
obj2 for in hasOwnProperty x 404,802 ops/sec ±0.42% (97 runs sampled) | ||
obj2 for Object.keys x 1,031,865 ops/sec ±0.67% (90 runs sampled) | ||
obj2 lodash _.clone x 419,223 ops/sec ±0.50% (95 runs sampled) | ||
obj2 node-v8-clone cloner x 4,560,158 ops/sec ±0.93% (92 runs sampled) | ||
obj3 = {_0: '_0', _1: '_1', ..., _999: '_999' } | ||
obj3 for in x 1,542 ops/sec ±2.34% (84 runs sampled) | ||
obj3 for in hasOwnProperty x 940 ops/sec ±1.26% (91 runs sampled) | ||
obj3 lodash _.clone x 2,112 ops/sec ±1.12% (93 runs sampled) | ||
obj3 node-v8-clone js cloner x 40,405 ops/sec ±2.58% (94 runs sampled) | ||
obj3 for in x 1,701 ops/sec ±0.59% (98 runs sampled) | ||
obj3 for in hasOwnProperty x 1,428 ops/sec ±0.62% (94 runs sampled) | ||
obj3 for Object.keys x 4,863 ops/sec ±0.59% (93 runs sampled) | ||
obj3 lodash _.clone x 2,136 ops/sec ±0.65% (97 runs sampled) | ||
obj3 node-v8-clone cloner x 40,657 ops/sec ±1.16% (92 runs sampled) | ||
obj4 = {0: 0, 1: 1, 2: 2, ..., 998: 998, 999: 999 } | ||
obj4 for in x 4,431 ops/sec ±2.43% (86 runs sampled) | ||
obj4 for in hasOwnProperty x 2,544 ops/sec ±1.62% (91 runs sampled) | ||
obj4 lodash _.clone x 5,407 ops/sec ±2.49% (82 runs sampled) | ||
obj4 node-v8-clone js cloner x 359,146 ops/sec ±2.70% (87 runs sampled) | ||
obj4 for in x 4,332 ops/sec ±0.53% (100 runs sampled) | ||
obj4 for in hasOwnProperty x 2,477 ops/sec ±0.58% (93 runs sampled) | ||
obj4 for Object.keys x 13,546 ops/sec ±0.61% (92 runs sampled) | ||
obj4 lodash _.clone x 5,905 ops/sec ±0.61% (98 runs sampled) | ||
obj4 node-v8-clone cloner x 372,176 ops/sec ±0.74% (93 runs sampled) | ||
``` | ||
@@ -68,18 +74,18 @@ Array shallow cloning: | ||
arr1 = [1, 2, 3, 4, 5] | ||
arr1 slice() x 8,230,013 ops/sec ±2.86% (91 runs sampled) | ||
arr1 [] for i < l i++ x 7,816,764 ops/sec ±2.50% (82 runs sampled) | ||
arr1 Array(l) for i < l i++ x 22,090,328 ops/sec ±1.36% (88 runs sampled) | ||
arr1 for in x 816,995 ops/sec ±1.50% (91 runs sampled) | ||
arr1 for in hasOwnProperty x 499,472 ops/sec ±2.83% (87 runs sampled) | ||
arr1 lodash _.clone x 1,520,163 ops/sec ±1.76% (84 runs sampled) | ||
arr1 node-v8-clone js cloner x 5,105,788 ops/sec ±2.07% (90 runs sampled) | ||
arr1 slice() x 9,171,117 ops/sec ±0.71% (89 runs sampled) | ||
arr1 [] for i < l i++ x 7,521,757 ops/sec ±0.79% (93 runs sampled) | ||
arr1 Array(l) for i < l i++ x 19,521,981 ops/sec ±1.65% (81 runs sampled) | ||
arr1 for in x 843,917 ops/sec ±0.61% (96 runs sampled) | ||
arr1 for in hasOwnProperty x 553,712 ops/sec ±0.47% (99 runs sampled) | ||
arr1 lodash _.clone x 1,826,144 ops/sec ±0.72% (96 runs sampled) | ||
arr1 node-v8-clone cloner x 5,541,714 ops/sec ±0.54% (91 runs sampled) | ||
arr2 = [0, 1, 2, ..., 998, 999] | ||
arr2 slice() x 522,115 ops/sec ±0.93% (95 runs sampled) | ||
arr2 [] for i < l i++ x 120,464 ops/sec ±1.55% (90 runs sampled) | ||
arr2 Array(l) for i < l i++ x 269,733 ops/sec ±1.39% (91 runs sampled) | ||
arr2 for in x 7,908 ops/sec ±1.91% (93 runs sampled) | ||
arr2 for in hasOwnProperty x 3,967 ops/sec ±0.92% (93 runs sampled) | ||
arr2 lodash _.clone x 413,365 ops/sec ±1.09% (93 runs sampled) | ||
arr2 node-v8-clone js cloner x 493,603 ops/sec ±0.59% (94 runs sampled) | ||
arr2 slice() x 534,954 ops/sec ±0.39% (91 runs sampled) | ||
arr2 [] for i < l i++ x 88,164 ops/sec ±0.59% (85 runs sampled) | ||
arr2 Array(l) for i < l i++ x 201,974 ops/sec ±0.76% (95 runs sampled) | ||
arr2 for in x 8,666 ops/sec ±0.61% (95 runs sampled) | ||
arr2 for in hasOwnProperty x 4,123 ops/sec ±0.47% (101 runs sampled) | ||
arr2 lodash _.clone x 157,718 ops/sec ±0.55% (83 runs sampled) | ||
arr2 node-v8-clone cloner x 552,515 ops/sec ±0.24% (81 runs sampled) | ||
``` | ||
@@ -86,0 +92,0 @@ RegExp shallow cloning: |
183
test/test.js
@@ -1,161 +0,36 @@ | ||
var assert = require("assert") | ||
var clone = require('..').clone; | ||
var assert = require('assert'); | ||
var Cloner = require('..').Cloner; | ||
var shared = require('./shared.js'); | ||
describe('clone', function(){ | ||
it('should clone null', function(){ | ||
var a = null; | ||
var b = clone(a); | ||
assert.equal(a, null); | ||
assert.equal(b, null); | ||
a = true; | ||
assert.equal(a, true); | ||
assert.equal(b, null); | ||
describe('new Cloner(false)', function(){ | ||
beforeEach(function(){ | ||
this.clone = function(value) { | ||
var cloner = new Cloner(false); | ||
return cloner.clone(value); | ||
}; | ||
}); | ||
it('should clone undefined', function(){ | ||
var a = undefined; | ||
var b = clone(a); | ||
assert.equal(a, undefined); | ||
assert.equal(b, undefined); | ||
}); | ||
it('should clone numbers', function(){ | ||
var a = 1; | ||
var b = clone(a); | ||
assert.equal(a, 1); | ||
assert.equal(b, 1); | ||
a += 1; | ||
assert.equal(a, 2); | ||
assert.equal(b, 1); | ||
}); | ||
it('should clone number objects', function(){ | ||
var a = new Number(1); | ||
var b = clone(a); | ||
assert.equal(a, 1); | ||
assert.equal(b, 1); | ||
assert.equal(a, 1); | ||
assert.equal(b, 1); | ||
shared.behavesAsShallow(); | ||
}); | ||
a.myprop = 2; | ||
assert.equal(a.myprop, 2); | ||
assert.equal(b.myprop, undefined); | ||
describe('new Cloner(true)', function(){ | ||
beforeEach(function(){ | ||
this.clone = function(value) { | ||
var cloner = new Cloner(true); | ||
return cloner.clone(value); | ||
}; | ||
}); | ||
it('should clone strings', function(){ | ||
var a = 'aaa'; | ||
var b = clone(a); | ||
assert.equal(a, 'aaa'); | ||
assert.equal(b, 'aaa'); | ||
a += 'bbb'; | ||
assert.equal(a, 'aaabbb'); | ||
assert.equal(b, 'aaa'); | ||
}); | ||
it('should clone strings objects', function(){ | ||
var a = new String('aaa'); | ||
var b = clone(a); | ||
assert.equal(a, 'aaa'); | ||
assert.equal(b, 'aaa'); | ||
assert.equal(a, 'aaa'); | ||
assert.equal(b, 'aaa'); | ||
shared.behavesAsShallow(); | ||
shared.behavesAsDeep(); | ||
shared.behavesAsDeepWCircular(); | ||
}); | ||
a.myprop = 2; | ||
assert.equal(a.myprop, 2); | ||
assert.equal(b.myprop, undefined); | ||
describe('new Cloner(true, false)', function(){ | ||
beforeEach(function(){ | ||
this.clone = function(value) { | ||
var cloner = new Cloner(true, false); | ||
return cloner.clone(value); | ||
}; | ||
}); | ||
it('should clone objects', function(){ | ||
var a = {x : 1, y: 2}; | ||
var b = clone(a); | ||
assert.equal(a.x, 1); | ||
assert.equal(a.y, 2); | ||
assert.equal(b.x, 1); | ||
assert.equal(b.y, 2); | ||
a.x = 3; | ||
assert.equal(a.x, 3); | ||
assert.equal(a.y, 2); | ||
assert.equal(b.x, 1); | ||
assert.equal(b.y, 2); | ||
}); | ||
it('should clone arrays', function(){ | ||
var a = [1, 2]; | ||
var b = clone(a); | ||
assert.equal(a[0], 1); | ||
assert.equal(a[1], 2); | ||
assert.equal(b[0], 1); | ||
assert.equal(b[1], 2); | ||
a[1] = 3; | ||
assert.equal(a[0], 1); | ||
assert.equal(a[1], 3); | ||
assert.equal(b[0], 1); | ||
assert.equal(b[1], 2); | ||
}); | ||
it('should clone instances', function(){ | ||
function clazz (c) { this.c = c; this.d = 2 }; | ||
clazz.prototype.getC = function() { return this.c; }; | ||
var a = new clazz(1); | ||
var b = clone(a); | ||
assert.equal(a.c, 1); | ||
assert.equal(a.getC(), 1); | ||
assert.equal(a.d, 2); | ||
assert.equal(b.c, 1); | ||
assert.equal(b.getC(), 1); | ||
assert.equal(b.d, 2); | ||
a.c = 3; | ||
assert.equal(a.c, 3); | ||
assert.equal(a.getC(), 3); | ||
assert.equal(a.d, 2); | ||
assert.equal(b.c, 1); | ||
assert.equal(b.getC(), 1); | ||
assert.equal(b.d, 2); | ||
}); | ||
it('should clone Date instances', function(){ | ||
var a = new Date(1980,2,3,4,5,6); | ||
var b = clone(a); | ||
assert.equal(a.getFullYear(), 1980); | ||
assert.equal(b.getFullYear(), 1980); | ||
a.setFullYear(1981); | ||
assert.equal(a.getFullYear(), 1981); | ||
assert.equal(b.getFullYear(), 1980); | ||
a.myprop = 2; | ||
assert.equal(a.myprop, 2); | ||
assert.equal(b.myprop, undefined); | ||
}); | ||
it('should clone RegExp instances', function(){ | ||
var a = new RegExp('a+', 'g'); | ||
var b = clone(a); | ||
assert.ok(a instanceof RegExp); | ||
assert.ok(b instanceof RegExp); | ||
assert.equal(a.lastIndex, 0); | ||
assert.equal(b.lastIndex, 0); | ||
a.exec('bba'); | ||
assert.equal(a.lastIndex, 3); | ||
assert.equal(b.lastIndex, 0); | ||
a.myprop = 2; | ||
assert.equal(a.myprop, 2); | ||
assert.equal(b.myprop, undefined); | ||
}); | ||
it('should clone Arguments', function(){ | ||
function getargs() { return arguments; }; | ||
var a = getargs(1, 2, 3); | ||
var b = clone(a); | ||
assert.deepEqual(a, getargs(1, 2, 3)); | ||
assert.deepEqual(b, getargs(1, 2, 3)); | ||
a[0] = 4; | ||
assert.deepEqual(a, getargs(4, 2, 3)); | ||
assert.deepEqual(b, getargs(1, 2, 3)); | ||
}); | ||
it('should clone Functions', function(){ | ||
var a = function(a, b, c) {}; | ||
var b = clone(a); | ||
assert.equal(a.toString(), b.toString()); | ||
}); | ||
it('should clone closures', function(){ | ||
var generator = function () { var i = 0; return function() { return ++i; }; }; | ||
var a = generator(); | ||
assert.equal(a(), 1); | ||
assert.equal(a(), 2); | ||
var b = clone(a); | ||
assert.equal(a(), 3); | ||
assert.equal(a(), 4); | ||
assert.equal(b(), 5); | ||
assert.equal(b(), 6); | ||
}); | ||
shared.behavesAsShallow(); | ||
shared.behavesAsDeep(); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Found 1 instance in 1 package
44474
0
20
1046
1
100
5
- Removedlodash@*
- Removedlodash@4.17.21(transitive)