Node.JS: Bad for the backend. Worse for the ecosystem.
The function makes a shallow copy of the input argument and proceeds to modify some of the nested objects. Did the author know the … operator (sugar for Object.assign()) doesn’t produce a deep copy of its input? The JSDoc doesn’t mention that the input argument is altered. Is this an undetected bug that bleeds into callers? 🤷
which is by no means a robust solution. First, JSON.stringify() fails when it encounters circular references. Secondly, this approach, like the … operator, violates encapsulation.
Making copies is a smell
Although nobody wants to write tedious code that copies objects, it’s usually a superior long-term alternative to the quick and dirty (and often embarrassing) JSON.parse(JSON.stringify()). But can you avoid making a copy in the first place? Can you at least reduce what needs to be copied? Answering these questions often leads to better designs and implementations.
CPU hogging is a smell
Making deep copies blocks other tasks from completing their work. Similarly, all CPU-intensive operations should be scrutinized. The functions and bodies that are called by for(), forEach(), etc. which don’t yield are a red flag. Refactor the functions in which they are found. Make them asynchronous. Yield periodically.
Mutating input arguments is a smell
Side-effects are bad but so is making copies — especially in Node. @param should at least mention that the argument is altered — extra points for describing how! Give your callers and future maintainers some love.
Functional languages like Elixir don’t even allow mutation. This eliminates an entire class of side-effect bugs at the expense of consuming more CPU and memory to make copies. To compensate, Elixir provides preemptive multitasking, rescuing developers from the conundrum of when to yield.
The only way to truly scale Node is by assigning one unit of work to a dedicated process where other tasks can’t starve it for resources. This is a profitable strategy for every hardware lessor that puts shareholders’ interests above all else: not only above the customer (developer) experience but above life itself. All things being equal, serverless technologies like AWS Lambda use more resources and release carbon faster compared to architectures that serve concurrent workloads in the same operating system processes. Considering who is impacted by global warming the most, choosing serverless is borderline immoral.
AWS, Microsoft, and Google love Node. Elixir, not so much.