0
# Object Operations
1
2
Methods for working with immutable objects including merging, property manipulation, and transformations.
3
4
## Capabilities
5
6
### merge
7
8
Merges objects immutably, with priority given to the provided object's values.
9
10
```javascript { .api }
11
/**
12
* Merge objects immutably with configurable behavior
13
* @param {Object} obj - Target object to merge into
14
* @param {Object|Array} other - Object or array of objects to merge
15
* @param {Object} [config] - Merge configuration options
16
* @param {boolean} [config.deep] - Perform deep merge of nested objects
17
* @param {string} [config.mode] - Merge mode: 'merge' (default) or 'replace'
18
* @param {Function} [config.merger] - Custom merger function for property conflicts
19
* @returns {Object} New immutable object with merged properties
20
*/
21
function merge(obj, other, config);
22
```
23
24
**Usage Examples:**
25
26
```javascript
27
const Immutable = require("seamless-immutable");
28
29
const obj = Immutable({status: "good", hypothesis: "plausible", errors: 0});
30
31
// Basic merge
32
const merged = obj.merge({status: "funky", hypothesis: "confirmed"});
33
// Result: {status: "funky", hypothesis: "confirmed", errors: 0}
34
35
// Merge multiple objects using array
36
const multiMerged = obj.merge([
37
{status: "funky", errors: 1},
38
{status: "groovy", errors: 2},
39
{status: "sweet"}
40
]);
41
// Result: {status: "sweet", errors: 2, hypothesis: "plausible"}
42
43
// Deep merge nested objects
44
const nested = Immutable({
45
user: {name: "Alice", age: 30},
46
settings: {theme: "dark", lang: "en"}
47
});
48
const deepMerged = nested.merge({
49
user: {age: 31, city: "NYC"}
50
}, {deep: true});
51
// Result: {user: {name: "Alice", age: 31, city: "NYC"}, settings: {theme: "dark", lang: "en"}}
52
53
// Replace mode - removes properties not in the new object
54
const replaced = obj.merge({status: "new"}, {mode: 'replace'});
55
// Result: {status: "new"} - other properties removed
56
57
// Custom merger function
58
const customMerged = obj.merge({errors: 5}, {
59
merger: (oldVal, newVal) => {
60
if (typeof oldVal === 'number' && typeof newVal === 'number') {
61
return oldVal + newVal; // Add numbers instead of replacing
62
}
63
return newVal;
64
}
65
});
66
// Result: {status: "good", hypothesis: "plausible", errors: 5} (0 + 5)
67
```
68
69
### replace
70
71
Replaces object properties entirely, equivalent to merge with `{mode: 'replace'}`.
72
73
```javascript { .api }
74
/**
75
* Replace object properties entirely
76
* @param {Object} obj - Target object
77
* @param {Object} value - New properties to replace with
78
* @param {Object} [config] - Configuration options
79
* @param {boolean} [config.deep] - Perform deep comparison and preserve identical nested objects
80
* @returns {Object} New immutable object containing only the replacement properties
81
*/
82
function replace(obj, value, config);
83
```
84
85
**Usage Examples:**
86
87
```javascript
88
const Immutable = require("seamless-immutable");
89
90
const obj1 = Immutable({a: {b: 'test'}, c: 'test'});
91
const obj2 = obj1.replace({a: {b: 'test'}});
92
// Result: {a: {b: 'test'}} - property 'c' removed
93
94
// With deep option - preserves identical nested objects for performance
95
const obj3 = obj1.replace({a: {b: 'test'}}, {deep: true});
96
console.log(obj1.a === obj3.a); // true - same nested object reference preserved
97
```
98
99
### set
100
101
Sets a single property on an object immutably.
102
103
```javascript { .api }
104
/**
105
* Set a property on an object immutably
106
* @param {Object} obj - Target object
107
* @param {string} property - Property key to set
108
* @param {*} value - Value to set
109
* @param {Object} [config] - Configuration options
110
* @param {boolean} [config.deep] - Deep merge if setting an object value
111
* @returns {Object} New immutable object with property set
112
*/
113
function set(obj, property, value, config);
114
```
115
116
**Usage Examples:**
117
118
```javascript
119
const Immutable = require("seamless-immutable");
120
121
const obj = Immutable({type: "parrot", subtype: "Norwegian Blue", status: "alive"});
122
123
// Basic property setting
124
const updated = obj.set("status", "dead");
125
// Result: {type: "parrot", subtype: "Norwegian Blue", status: "dead"}
126
127
// Deep merge when setting object values
128
const withAddress = obj.set("address", {city: "London", country: "UK"}, {deep: true});
129
130
// Static method usage
131
const staticUpdate = Immutable.set(obj, "status", "sleeping");
132
```
133
134
### without
135
136
Removes properties from an object immutably.
137
138
```javascript { .api }
139
/**
140
* Remove properties from an object immutably
141
* @param {Object} obj - Target object
142
* @param {...string|Array|Function} keys - Property keys to remove, array of keys, or predicate function
143
* @returns {Object} New immutable object without specified properties
144
*/
145
function without(obj, ...keys);
146
```
147
148
**Usage Examples:**
149
150
```javascript
151
const Immutable = require("seamless-immutable");
152
153
const obj = Immutable({the: "forests", will: "echo", with: "laughter"});
154
155
// Remove single property
156
const without1 = obj.without("with");
157
// Result: {the: "forests", will: "echo"}
158
159
// Remove multiple properties as separate arguments
160
const without2 = obj.without("will", "with");
161
// Result: {the: "forests"}
162
163
// Remove multiple properties as array
164
const without3 = obj.without(["will", "with"]);
165
// Result: {the: "forests"}
166
167
// Remove using predicate function
168
const without4 = obj.without((value, key) => key === "the" || value === "echo");
169
// Result: {with: "laughter"}
170
171
// Numeric keys are handled correctly
172
const objWithNumbers = Immutable({0: "zero", 1: "one", name: "test"});
173
const withoutNumbers = objWithNumbers.without(0, 1);
174
// Result: {name: "test"}
175
```
176
177
### update
178
179
Updates a property using an updater function.
180
181
```javascript { .api }
182
/**
183
* Update a property using an updater function
184
* @param {Object} obj - Target object
185
* @param {string} property - Property key to update
186
* @param {Function} updater - Function that receives current value and returns new value
187
* @param {...*} [args] - Additional arguments passed to updater function
188
* @returns {Object} New immutable object with updated property
189
*/
190
function update(obj, property, updater, ...args);
191
```
192
193
**Usage Examples:**
194
195
```javascript
196
const Immutable = require("seamless-immutable");
197
198
// Simple increment
199
function inc(x) { return x + 1; }
200
const obj = Immutable({foo: 1});
201
const incremented = obj.update("foo", inc);
202
// Result: {foo: 2}
203
204
// Updater with additional arguments
205
function add(x, y) { return x + y; }
206
const added = obj.update("foo", add, 10);
207
// Result: {foo: 11}
208
209
// String manipulation
210
const user = Immutable({name: "alice"});
211
const capitalized = user.update("name", name => name.toUpperCase());
212
// Result: {name: "ALICE"}
213
214
// Working with arrays
215
const data = Immutable({items: [1, 2, 3]});
216
const withNewItem = data.update("items", items => items.concat(4));
217
// Result: {items: [1, 2, 3, 4]}
218
```
219
220
### asMutable (Object-specific)
221
222
Converts an immutable object to a mutable copy.
223
224
```javascript { .api }
225
/**
226
* Convert immutable object to mutable copy
227
* @param {Object} obj - Immutable object to convert
228
* @param {Object} [options] - Conversion options
229
* @param {boolean} [options.deep] - Recursively convert nested immutable structures
230
* @returns {Object} Mutable copy of the object
231
*/
232
function asMutable(obj, options);
233
```
234
235
**Usage Examples:**
236
237
```javascript
238
const Immutable = require("seamless-immutable");
239
240
const obj = Immutable({when: "the", levee: "breaks"});
241
const mutableObject = obj.asMutable();
242
243
// Now can mutate directly
244
mutableObject.have = "no place to go";
245
console.log(mutableObject); // {when: "the", levee: "breaks", have: "no place to go"}
246
247
// Deep conversion for nested structures
248
const nested = Immutable({
249
user: {name: "Alice"},
250
hobbies: ["reading", "coding"]
251
});
252
253
const shallowMutable = nested.asMutable();
254
// shallowMutable.user.name = "Bob"; // Would still throw - nested objects still immutable
255
256
const deepMutable = nested.asMutable({deep: true});
257
deepMutable.user.name = "Bob"; // Works - all nested structures are now mutable
258
deepMutable.hobbies.push("gaming"); // Also works
259
```
260
261
## Instance vs Static Methods
262
263
All object methods are available in both instance and static forms:
264
265
```javascript
266
const Immutable = require("seamless-immutable");
267
const obj = Immutable({name: "Alice", age: 30});
268
269
// Instance methods (default API)
270
const merged1 = obj.merge({age: 31});
271
const updated1 = obj.set("status", "active");
272
const filtered1 = obj.without("age");
273
274
// Static methods (static API - avoids method pollution)
275
const Immutable = require("seamless-immutable").static;
276
const merged2 = Immutable.merge(obj, {age: 31});
277
const updated2 = Immutable.set(obj, "status", "active");
278
const filtered2 = Immutable.without(obj, "age");
279
```
280
281
Both approaches are functionally identical - choose based on your preference for avoiding method name collisions or preferring shorter syntax.