Skip to content

💅 Object.assign on Accumulators SHOULD Be Allowed (Sometimes) #6675

@mattfysh

Description

@mattfysh

Environment information

I am using Biome strictly in the IDE, so this n/a for me.

Rule name

no-accumulating-spread

Playground link

https://biomejs.dev/playground/?code=YwBvAG4AcwB0ACAAYQByAHIAYQB5AE8AZgBPAGIAagBzACAAPQAgAFsAewAKACAAIABoAGUAbABsAG8AOgAgACcAdwBvAHIAbABkACEAJwAKAH0AXQAKAAoALwAvACAAZwBvAG8AZAAKAGEAcgByAGEAeQBPAGYATwBiAGoAcwAuAHIAZQBkAHUAYwBlACgAKABhAGMAYwB1AG0ALAAgAG8AYgBqACkAIAA9AD4AIABPAGIAagBlAGMAdAAuAGEAcwBzAGkAZwBuACgAYQBjAGMAdQBtACwAIABvAGIAagApACwAIAB7AH0AKQAKAAoALwAvACAAYgBhAGQACgBhAHIAcgBhAHkATwBmAE8AYgBqAHMALgByAGUAZAB1AGMAZQAoACgAYQBjAGMAdQBtACwAIABvAGIAagApACAAPQA%2BACAATwBiAGoAZQBjAHQALgBhAHMAcwBpAGcAbgAoAHsAfQAsACAAYQBjAGMAdQBtACwAIABvAGIAagApACwAIAB7AH0AKQA%3D

Expected result

The no-accumulating-spread rule should not throw an error or raise a warning when we're using Object.assign to add additional properties to the existing, in-memory accumulated object

The rational provided in the issue where this was added (#5277) was that spread syntax is syntactic sugar for Object.assign

This is only a half-truth, what the author really means when referring to the O(n^2) problem is that we should not be creating a new object in each loop of the reducer, where every key/value pair is copied across memory locations during iteration

However, if you're using Object.assign directly on the memo object, you're not creating a new object, you're simply assigning new values from the next value to the existing in-memory object. To demonstrate:

const arrs = [{ a: 1 }, { b: 2 }, { c: 3 }]

// this is bad, the spread syntax creates a new object upon each iteration
arrs.reduce((a, b) => {
  return { ...a, ...b }
}, {})

// this is the canonical implementation of the above bad pattern
arrs.reduce((a, b) => {
  return Object.assign({}, a, b) // <-- new object created on every loop
}, {})

// however, this usage of Object.assign is completely fine and does not lead to performance issues:
arrs.reduce((a, b) => {
  return Object.assign(a, b)
}, {})

Code of Conduct

  • I agree to follow Biome's Code of Conduct

Metadata

Metadata

Assignees

Labels

A-LinterArea: linterL-JavaScriptLanguage: JavaScript and super languagesS-Bug-confirmedStatus: report has been confirmed as a valid bug

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions