Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add cloneDeep function #81

Merged
merged 6 commits into from
Jul 12, 2024
Merged

feat: add cloneDeep function #81

merged 6 commits into from
Jul 12, 2024

Conversation

aleclarson
Copy link
Member

@aleclarson aleclarson commented Jul 4, 2024

Tip

The owner of this PR can publish a preview release by commenting /publish in this PR. Afterwards, anyone can try it out by running pnpm add radashi@pr<PR_NUMBER>.

Summary

Note: There are multiple unrelated PRs in here. Look for the cloneDeep one.

I will add more details soon. Stay tuned!

So my initial attempt tried to use traverse (#59), but I found it really only complicated things and the workarounds likely reduced performance.

The current incarnation uses the concept of "cloning strategies". The default strategy aims to be comprehensive, thereby avoiding footguns at the cost of performance (not yet benchmarked).

Sane Default Logic
By default, plain objects and class instances have all non-enumerable and computed properties preserved in their clones.

Faster Cloning
You can pass the FastCloningStrategy for better performance as long as you don't mind all plain objects and class instances being cloned with {...obj} (losing the original prototype, cementing any computed properties, and losing non-enumerable own keys). Note that built-in complex objects like RegExp/Date are still not cloned with this cloning strategy.

Custom Cloning Strategies
You can partially override any method in the default cloning strategy. Your override can return null to use the default logic. It can return the original object to skip cloning for it.

// Override the cloneObject method to skip frozen objects.
cloneDeep(obj, {
  cloneObject: obj => Object.isFrozen(obj) ? obj : null,
})

// Override the cloneOther method to support RegExp cloning.
cloneDeep(obj, {
  cloneOther: obj => isRegExp(obj) ? new RegExp(obj.source, obj.flags) : obj,
})

Related issue, if any:

Depends on #77

Resolves #55

For any code change,

  • Related documentation has been updated, if needed
  • Related tests have been added or updated, if needed
  • Related benchmarks have been added or updated, if needed

Does this PR introduce a breaking change?

No

Bundle impact

Status File Size
A src/object/cloneDeep.ts 1090

@aleclarson aleclarson force-pushed the feat/cloneDeep branch 2 times, most recently from d5a96c8 to 9c3fe7e Compare July 10, 2024 20:52
@aleclarson aleclarson marked this pull request as ready for review July 11, 2024 01:15
@aleclarson aleclarson force-pushed the main branch 2 times, most recently from 2154f96 to 6a4b4f6 Compare July 12, 2024 00:23
@aleclarson aleclarson merged commit 46ee7c7 into main Jul 12, 2024
4 checks passed
@aleclarson aleclarson deleted the feat/cloneDeep branch July 12, 2024 00:45
Copy link

A new beta version 12.2.0-beta.5b5a0a7 has been published to NPM. 🚀

To install:

The radashi@beta tag also includes this PR.

See the changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant