copy-anything
Advanced tools
Comparing version 1.2.4 to 1.3.0
@@ -5,2 +5,17 @@ 'use strict'; | ||
function assignProp(carry, key, newVal, originalObject) { | ||
var propType = originalObject.propertyIsEnumerable(key) | ||
? 'enumerable' | ||
: 'nonenumerable'; | ||
if (propType === 'enumerable') | ||
carry[key] = newVal; | ||
if (propType === 'nonenumerable') { | ||
Object.defineProperty(carry, key, { | ||
value: newVal, | ||
enumerable: false, | ||
writable: true, | ||
configurable: true | ||
}); | ||
} | ||
} | ||
/** | ||
@@ -18,6 +33,9 @@ * Copy (clone) an object and all its props recursively to get rid of any prop referenced of the original object. Arrays are also cloned, however objects inside arrays are still linked. | ||
return target; | ||
return Object.keys(target) | ||
.reduce(function (carry, key) { | ||
var props = Object.getOwnPropertyNames(target); | ||
var symbols = Object.getOwnPropertySymbols(target); | ||
return props.concat(symbols).reduce(function (carry, key) { | ||
// @ts-ignore | ||
var val = target[key]; | ||
carry[key] = copy(val); | ||
var newVal = copy(val); | ||
assignProp(carry, key, newVal, target); | ||
return carry; | ||
@@ -24,0 +42,0 @@ }, {}); |
import { isArray, isPlainObject } from 'is-what'; | ||
function assignProp(carry, key, newVal, originalObject) { | ||
var propType = originalObject.propertyIsEnumerable(key) | ||
? 'enumerable' | ||
: 'nonenumerable'; | ||
if (propType === 'enumerable') | ||
carry[key] = newVal; | ||
if (propType === 'nonenumerable') { | ||
Object.defineProperty(carry, key, { | ||
value: newVal, | ||
enumerable: false, | ||
writable: true, | ||
configurable: true | ||
}); | ||
} | ||
} | ||
/** | ||
@@ -15,6 +30,9 @@ * Copy (clone) an object and all its props recursively to get rid of any prop referenced of the original object. Arrays are also cloned, however objects inside arrays are still linked. | ||
return target; | ||
return Object.keys(target) | ||
.reduce(function (carry, key) { | ||
var props = Object.getOwnPropertyNames(target); | ||
var symbols = Object.getOwnPropertySymbols(target); | ||
return props.concat(symbols).reduce(function (carry, key) { | ||
// @ts-ignore | ||
var val = target[key]; | ||
carry[key] = copy(val); | ||
var newVal = copy(val); | ||
assignProp(carry, key, newVal, target); | ||
return carry; | ||
@@ -21,0 +39,0 @@ }, {}); |
{ | ||
"name": "copy-anything", | ||
"version": "1.2.4", | ||
"version": "1.3.0", | ||
"description": "An optimised way to copy'ing an object. A small and simple integration", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.cjs.js", |
@@ -19,2 +19,4 @@ # Copy anything 🎭 | ||
- works with arrays and objects in arrays! | ||
- supports symbols | ||
- supports enumerable & nonenumerable props | ||
- **does not break special class instances** ‼️ | ||
@@ -21,0 +23,0 @@ |
import { isPlainObject, isArray } from 'is-what' | ||
function assignProp (carry, key, newVal, originalObject) { | ||
const propType = originalObject.propertyIsEnumerable(key) | ||
? 'enumerable' | ||
: 'nonenumerable' | ||
if (propType === 'enumerable') carry[key] = newVal | ||
if (propType === 'nonenumerable') { | ||
Object.defineProperty(carry, key, { | ||
value: newVal, | ||
enumerable: false, | ||
writable: true, | ||
configurable: true | ||
}) | ||
} | ||
} | ||
/** | ||
@@ -13,8 +28,12 @@ * Copy (clone) an object and all its props recursively to get rid of any prop referenced of the original object. Arrays are also cloned, however objects inside arrays are still linked. | ||
if (!isPlainObject(target)) return target | ||
return Object.keys(target) | ||
const props = Object.getOwnPropertyNames(target) | ||
const symbols = Object.getOwnPropertySymbols(target) | ||
return [...props, ...symbols] | ||
.reduce((carry, key) => { | ||
// @ts-ignore | ||
const val = target[key] | ||
carry[key] = copy(val) | ||
const newVal = copy(val) | ||
assignProp(carry, key, newVal, target) | ||
return carry | ||
}, {}) | ||
} |
@@ -115,1 +115,47 @@ import test from 'ava' | ||
}) | ||
test('symbols as keys', t => { | ||
let res, target | ||
const mySymbol = Symbol('mySymbol') | ||
target = { value: 42, [mySymbol]: 'hello' } | ||
res = copy(target) | ||
// change original | ||
target.value = 1 | ||
target[mySymbol] = 2 | ||
t.is(res.value, 42) | ||
t.is(res[mySymbol], 'hello') | ||
t.is(target.value, 1) | ||
t.is(target[mySymbol], 2) | ||
}) | ||
test('nonenumerable keys', t => { | ||
let target, res | ||
const mySymbol = Symbol('mySymbol') | ||
target = { value: 42 } | ||
Object.defineProperty(target, 'id', { | ||
value: 1, | ||
writable: true, | ||
enumerable: false, | ||
configurable: true | ||
}) | ||
Object.defineProperty(target, mySymbol, { | ||
value: 'original', | ||
writable: true, | ||
enumerable: false, | ||
configurable: true | ||
}) | ||
res = copy(target) | ||
// change original | ||
target.id = 100 | ||
target[mySymbol] = 'new' | ||
target.value = 300 | ||
t.is(res.value, 42) | ||
t.is(res.id, 1) | ||
t.is(res[mySymbol], 'original') | ||
t.is(Object.keys(res).length, 1) | ||
t.true(Object.keys(res).includes('value')) | ||
t.is(target.id, 100) | ||
t.is(target[mySymbol], 'new') | ||
t.is(target.value, 300) | ||
t.is(Object.keys(target).length, 1) | ||
}) |
17462
388
91