Skip to content

Commit

Permalink
fix: clone custom class instances;
Browse files Browse the repository at this point in the history
- Closes #14
- Removes invalid test case
  • Loading branch information
lukeed committed Jul 4, 2020
1 parent 74622f5 commit c873e9e
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 32 deletions.
31 changes: 20 additions & 11 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,26 @@ export default function klona(x) {
var k, tmp, str=Object.prototype.toString.call(x);

if (str === '[object Object]') {
tmp = {};
for (k in x) {
if (k === '__proto__') {
Object.defineProperty(tmp, k, {
value: klona(x[k]),
configurable: 1,
enumerable: 1,
writable: 1,
});
} else {
tmp[k] = klona(x[k]);
if (x.constructor !== Object && typeof x.constructor === 'function') {
tmp = new x.constructor();
for (k in x) {
if (tmp[k] === void 0) {
tmp[k] = klona(x[k]);
}
}
} else {
tmp = {}; // null
for (k in x) {
if (k === '__proto__') {
Object.defineProperty(tmp, k, {
value: klona(x[k]),
configurable: true,
enumerable: true,
writable: true,
});
} else {
tmp[k] = klona(x[k]);
}
}
}
return tmp;
Expand Down
33 changes: 12 additions & 21 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,39 +65,30 @@ Classes('class', () => {
const output = klona(input);

assert.deepEqual(input, output);
assert.equal(input.constructor, output.constructor);
assert.equal(output.constructor.name, 'Foobar');

output.foobar = 123;
// @ts-ignore
assert.notEqual(input.foobar, 123);
});

Classes.run();

// ---

const Constructor = suite('constructor');

Constructor('hijack', () => {
let count = 0;

class Foo {}
function CustomArray() {
count++;
}

const input = new Foo();
assert.equal(input.constructor.name, 'Foo');

input.constructor = CustomArray;
assert.equal(input.constructor.name, 'CustomArray');
// @see https://github.com/lukeed/klona/issues/14
Classes('prototype', () => {
function Test () {}
Test.prototype.val = 42;

const input = new Test();
const output = klona(input);

assert.deepEqual(input, output);

assert.equal(count, 0, '~> did not call constructor');
assert.deepEqual(output.constructor, Test);
assert.deepEqual(output.__proto__, { val: 42 });
assert.deepEqual(output, {});
});

Constructor.run();
Classes.run();

// ---

Expand Down

0 comments on commit c873e9e

Please sign in to comment.