pvorb / clone

deeply clone arbitrary objects in javascript
https://www.npmjs.com/package/clone
MIT License
781 stars 128 forks source link

WeakMap and WeakSet errors #111

Open terrymorse58 opened 4 years ago

terrymorse58 commented 4 years ago

The following clone test of an array containing a WeakMap produces an error:

// WeakMap test
const options = { includeNonEnumerable: true };

let wm = new WeakMap();
let obj = { foo: "I am foo" };
wm.set(obj, 42);
let src = [1, 2, wm, "bar"];

let dest = clone(src, options);
dest[1] = 3.1416;

console.log(src);
//  [ 1, 2, WeakMap { <items unknown> }, 'bar' ]
console.log(dest);
//  [ 1, 3.1416, WeakMap {}, 'bar' ]

let destMap = dest[2];
console.log(destMap instanceof WeakMap);
// true

destMap.has(obj);
//  TypeError: Method WeakMap.prototype.has called on incompatible receiver #<WeakMap>

An identical error occurs when running a similar test with WeakSet:

// TypeError: Method WeakSet.prototype.has called on incompatible receiver #<WeakSet>
terrymorse58 commented 4 years ago

Also, in the following test, clone failed to copy the ArrayCustom prototype.

class ArrayCustom extends Array {
  custom() { return true; }
}
let src = [1, 2, ArrayCustom.from(["I", "am", "foo"])];
let dest = clone(src);
dest[1] = 2.00001;

console.log(src);
// [ 1, 2, ArrayCustom [ 'I', 'am', 'foo' ] ]
console.log(dest);
// [ 1, 2.00001, [ 'I', 'am', 'foo' ] ]

let destCustom = dest[2];
if (!(destCustom instanceof ArrayCustom)) {
  throw "Error: failed to preserve ArrayCustom prototype";
}
// Error: failed to preserve ArrayCustom prototype