Skip to content

Commit fee065a

Browse files
authored
Improve the 'Alternatives' section
Improve the 'Alternatives' section and add @mrjacobbloom's suggestion (#1)
1 parent fc2f6ca commit fee065a

File tree

1 file changed

+91
-5
lines changed

1 file changed

+91
-5
lines changed

README.md

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,101 @@ The second consequence is that in a particular object spread, a minus operator c
104104
105105
For sure, there are existing alternatives to the proposed minus operator.
106106
107-
First of all, it's the [delete operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete). Although, it cannot be used declaratively, meaning that the object produced by object spread must be assgned to a variable first, and only then we can remove the property from it by its key.
107+
1. The [delete operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete). Although, it cannot be used declaratively, meaning that the object produced by object spread must be assgned to a variable first, and only then we can remove the property from it by its key:
108+
```js
109+
const obj = {
110+
a: 'aValue',
111+
b: 'bValue',
112+
key: 'value',
113+
};
108114
109-
Second approach is using `Object.keys(obj).reduce(...)`, which is a block of repeated code that takes a bit of time to read and understand.
115+
// To avoid mutating the original object, we create a copy
116+
const result = { ...obj };
117+
// Then we imperatively delete the key
118+
delete result.key;
119+
// And since the above line isn't an rvalue, we have to return the result explicitly
120+
return result;
121+
```
110122

111-
The third approach is even more imperative – it's `for ... of` loop or any related alternative.
123+
2. `Object.keys(obj).filter(...).reduce(...)` which is a block of repeated code that takes a bit of time to read and understand:
124+
```js
125+
const obj = {
126+
a: 'aValue',
127+
b: 'bValue',
128+
key: 'value',
129+
};
112130

113-
The fourth possible solution is to manually assign all the properties, manually omitting the ones that has to be omitted. It's quite a lot boilerplate code.
131+
// A bit wordy, ineffective, and too difficult to read
132+
return Object
133+
.keys(obj)
134+
.filter((k) => k !== 'key')
135+
.reduce((acc, k) => ({ ...acc, [k]: obj[k] }), {});
136+
```
114137

115-
And the last possible solution is to assign undefined to the key to be removed – but it's far from the ideal way to solve that issue, because the key would still exist in the object, meaning that if we enumerate through all the properties, there will be an undefined value for that key.
138+
3. The third approach is even more imperative – it's `for ... of` loop or any related alternative.
139+
```js
140+
const obj = {
141+
a: 'aValue',
142+
b: 'bValue',
143+
key: 'value',
144+
};
145+
146+
// A bit wordy `for ... of` loop
147+
const result = {};
148+
for (const [key, value] of Object.entries(obj)) {
149+
if (key !== 'key') {
150+
result[key] = value;
151+
}
152+
}
153+
// Also, loops aren't rvalues and thus, we have to return explicitly
154+
return result;
155+
```
156+
157+
4. Another possible solution is to manually assign all the properties, manually omitting the ones that has to be omitted. It's quite a lot boilerplate code.
158+
```js
159+
const obj = {
160+
a: 'aValue',
161+
b: 'bValue',
162+
key: 'value',
163+
};
164+
165+
// `obj` might have too many properties here and this might be inconvenient
166+
// to manually enumerate all of them
167+
return {
168+
a: obj.a,
169+
b: obj.b,
170+
};
171+
```
172+
173+
5. Using spread with destructuring operator, to filter out all the undesired properties (for example, [`const { propertyIDontWant, ...newObject } = origObject; return newObject;`](https://github.com/devlato/proposal-plus-minus-spread/issues/1)).
174+
```js
175+
const obj = {
176+
a: 'aValue',
177+
b: 'bValue',
178+
key: 'value',
179+
};
180+
181+
// `result` can't be returned directly from here, and also, an unnecessary variable `key` is created
182+
const { key, ...result } = obj;
183+
// So we have to return explicitly
184+
return result;
185+
```
186+
187+
6. And the last possible solution is to assign undefined to the key to be removed – but it's far from the ideal way to solve that issue, because the key would still exist in the object, meaning that if we enumerate through all the properties, there will be an undefined value for that key.
188+
```js
189+
const obj = {
190+
a: 'aValue',
191+
b: 'bValue',
192+
key: 'value',
193+
};
194+
195+
return {
196+
...obj,
197+
// Even though `obj[key]` is `undefined`, `obj.hasOwnProperty('key')` would return true,
198+
// producing undesired side effects
199+
key: undefined,
200+
};
201+
```
116202

117203

118204
## Additional proposal: plus operator (optional)

0 commit comments

Comments
 (0)