From d8720a348fc3108f120c068139705decaf7435f5 Mon Sep 17 00:00:00 2001 From: Luke Edwards Date: Tue, 15 Sep 2020 11:39:31 -0700 Subject: [PATCH] fix(full): ensure prototype methods are copied; - Closes #24 --- src/full.js | 4 +-- test/suites/class.js | 59 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/full.js b/src/full.js index 24bf19f..b5f86c3 100644 --- a/src/full.js +++ b/src/full.js @@ -11,7 +11,7 @@ export function klona(x) { var i=0, k, list, tmp, str=Object.prototype.toString.call(x); if (str === '[object Object]') { - tmp = typeof x.constructor === 'function' ? new x.constructor() : Object.create(null); + tmp = Object.create(x.__proto__ || null); } else if (str === '[object Array]') { tmp = Array(x.length); } else if (str === '[object Set]') { @@ -39,7 +39,7 @@ export function klona(x) { } if (tmp) { - for (list = Object.getOwnPropertySymbols(x); i < list.length; i++) { + for (list=Object.getOwnPropertySymbols(x); i < list.length; i++) { set(tmp, list[i], Object.getOwnPropertyDescriptor(x, list[i])); } diff --git a/test/suites/class.js b/test/suites/class.js index 9d22d7e..5d28822 100644 --- a/test/suites/class.js +++ b/test/suites/class.js @@ -34,6 +34,65 @@ export default function (klona) { assert.equal(output.val, 42); }); + Classes('prototype methods :: manual', () => { + function Test() {} + + Test.prototype = { + count: 0, + increment() { + this.count++; + } + }; + + const input = new Test(); + const output = klona(input); + + assert.equal(input.count, 0); + assert.equal(output.count, 0); + + assert.equal(typeof input.increment, 'function'); + assert.equal(typeof output.increment, 'function'); + + output.increment(); + assert.equal(input.count, 0); + assert.equal(output.count, 1); + + input.increment(); + assert.equal(input.count, 1); + assert.equal(output.count, 1); + }); + + Classes('prototype methods :: class', () => { + class Test { + constructor() { + this.count = 0; + } + increment() { + this.count++ + } + } + + const input = new Test(); + const output = klona(input); + + assert.deepEqual(input, output); + assert.deepEqual(output.__proto__, Test.prototype); + + assert.equal(input.count, 0); + assert.equal(output.count, 0); + + assert.equal(typeof input.increment, 'function'); + assert.equal(typeof output.increment, 'function'); + + output.increment(); + assert.equal(input.count, 0); + assert.equal(output.count, 1); + + input.increment(); + assert.equal(input.count, 1); + assert.equal(output.count, 1); + }); + Classes('constructor properties', () => { function Test (num) { this.value = num;