index.js 1.1 KB

123456789101112131415161718192021222324252627282930313233343536
  1. import { isArray, isPlainObject } from 'is-what';
  2. function assignProp(carry, key, newVal, originalObject, includeNonenumerable) {
  3. const propType = {}.propertyIsEnumerable.call(originalObject, key) ? "enumerable" : "nonenumerable";
  4. if (propType === "enumerable")
  5. carry[key] = newVal;
  6. if (includeNonenumerable && propType === "nonenumerable") {
  7. Object.defineProperty(carry, key, {
  8. value: newVal,
  9. enumerable: false,
  10. writable: true,
  11. configurable: true
  12. });
  13. }
  14. }
  15. function copy(target, options = {}) {
  16. if (isArray(target)) {
  17. return target.map((item) => copy(item, options));
  18. }
  19. if (!isPlainObject(target)) {
  20. return target;
  21. }
  22. const props = Object.getOwnPropertyNames(target);
  23. const symbols = Object.getOwnPropertySymbols(target);
  24. return [...props, ...symbols].reduce((carry, key) => {
  25. if (isArray(options.props) && !options.props.includes(key)) {
  26. return carry;
  27. }
  28. const val = target[key];
  29. const newVal = copy(val, options);
  30. assignProp(carry, key, newVal, target, options.nonenumerable);
  31. return carry;
  32. }, {});
  33. }
  34. export { copy };