
Security News
gem.coop Tests Dependency Cooldowns as Package Ecosystems Move to Slow Down Attacks
gem.coop is testing registry-level dependency cooldowns to limit exposure during the brief window when malicious gems are most likely to spread.
js-object-clone
Advanced tools
Deep cloning and comparison for ES5
// just for convenience
var log = function(){ console.log.apply(console, [].slice.call(arguments)) };
var src = { name: 'dankogai', lang: ['perl'] };
var dst = Object.clone(src); // shallow copy
log( Object.is(src, dst) ); // false
log( Object.equals(src, dst) ); // true
dst.lang.push('javascript');
log(JSON.stringify(src.lang) ); // ["perl","javascript"] because dst is shallow-copied
dst = Object.clone(src, true); // deep copy
dst.lang = dst.lang.reverse();
log( JSON.stringify(src.lang) ); // ["perl","javascript"]
log( JSON.stringify(dst.lang) ); // ["javascript","perl"]
EcmaScript 5 compliance.
This script installs following functions to Object.
If the follwing ES6 functions are missing they are polyfilled.
Object.is()Object.isnt()cf. http://wiki.ecmascript.org/doku.php?id=harmony:egal
Clones the object obj. When deep is true, it attempts to deep
clone obj.
For spec, see below.
Unlike many other implementations of object cloners, This one:
Object.getOwnPropertyDescriptor() returnsObject.preventExtensions()Object.seal()Object.freeze()You can clone custom objects so long as its constructor is written in JavaScript:
var Point = function(x, y) {
if (!(this instanceof Point)) return new Point(x, y);
this.x = x*1;
this.y = y*1;
};
Point.prototype = {
distance: function(pt) {
if (!pt) pt = Point(0,0);
var dx = this.x - pt.x;
var dy = this.y - pt.y;
return Math.sqrt(dx*dx + dy*dy);
}
};
var src = Point(3,4);
var dst = Object.clone(src, true);
log( src === dst ); // false
log( Object.equals(src, dst) ); // true
log( dst.distance(Point(0,0)) ); // 5
If the type of obj is unsupported, it throws TypeError:
dst = Object.clone(new Error); // [object Error] unsupported
Note DOM Elements are not supported. It already has .cloneNode so use it.
cf. https://developer.mozilla.org/en-US/docs/DOM/Node.cloneNode
It is rather trivial to add support for that since all you have to do
is delegate it to obj.cloneNode( deep ) (as a matter of fact my
early code did support that). But the author decided to drop that
since uneval() of Firefox does not support that.
Compares the value of each property in objX and objY and returns
true iff all properties are equal, otherwise false.
Like Object.clone(), Object.equals():
Version 0.3.0 introduced the third argument to Object.clone() and
Object.equals() which enables more minute control on how objects
are compared or cloned. It is a object with following default.
{
descriptors: true,
extensibility: true,
enumerator: Object.getOwnPropertyNames
}
If false, descriptor specs are ignored except for value.
src = {};
defineProperty(src, 0, {value:1});
dst = Object.clone(src, true, {descriptor:false} );
log(Object.equals(dst, src) ); // false;
log(Object.equals(dst, src, {descriptor:false})); // true;
If false, extensibility is ignored
src = {};
Object.freeze(src);
dst = Object.clone(src, true, {extensibility:false});
log(Object.equals(dst, src) ); // false;
log(Object.equals(dst, src, {extensibility:true})); // true;
Set the function used to enumurate object. Change it to Object.keys
and all non-enumerable properties are ignored.
The example below emulates _.clone and _.isEqual():
var spec = {
descriptors: false,
extensibility: false,
enumerator: Object.keys
};
if (!_) _ = {};
_.clone = function(src) { return Object.clone(src, false, spec) };
_.isEqual = function(x, y){ return Object.equals(x, y, spec) };
You can even set filter like this:
var ignore__ = function(desc, key, obj) {
return !key.match(/^__/);
};
src = {0:1, __id__:'src'};
dst = Object.clone(src, true, {filter:ignore__});
log(Object.equals(dst, src) ); // false;
log(Object.equals(dst, src, {filter:ignore__})); // true;
Like [].filter, the call back function take three arguments
desc
The descriptor of the value. Note it is not the value itselfkey
The key. For most cases you need only this.obj
The whole objectAs of 0.2.0, Object.clone() and Object.equals() handle
circular references iff ES6 WeakMap is supported. As of this writing,
the following JS engines suppor that.
--harmonychrome://flags/.cf. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/WeakMap
Like JSON, Object.clone() and Object.equals() cannot handle
circular references unless WeakMap is supported.
It is not impossible to handle circular references in JavaScript since
you can check if the objects are identical via === operator. Yet it
is very impractical without object ID like object_id of Ruby or
refaddr of Perl. Without object ID you have to linear search just
to check if the object is already visited. As a matter of fact the
reference implementation of Map and Set of ES6 resorts to linear
search.
With ES5 you can add hidden, immutable properties like .__id__ via
Object.defineProperty but mutating objects for that is rude if not
unforgivable.
Available only on firefox. Handles circular references.
Lacks deep cloning support and ES5 support. One of the reason why I resorted to writing this.
Lo-dash has _.cloneDeep() yet still lacks ES5 suppport.
Roughly the same but Blob, File and other user-agent specific objects are not yet supported. Unfortunately it is used only internally to exchange data with WebWorkers.
FAQs
Deep cloning and comparison for ES5
The npm package js-object-clone receives a total of 53 weekly downloads. As such, js-object-clone popularity was classified as not popular.
We found that js-object-clone demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
gem.coop is testing registry-level dependency cooldowns to limit exposure during the brief window when malicious gems are most likely to spread.

Security News
Following multiple malicious extension incidents, Open VSX outlines new safeguards designed to catch risky uploads earlier.

Research
/Security News
Threat actors compromised four oorzc Open VSX extensions with more than 22,000 downloads, pushing malicious versions that install a staged loader, evade Russian-locale systems, pull C2 from Solana memos, and steal macOS credentials and wallets.