README.md (8250B)
1 <!-- 2 3 @license Apache-2.0 4 5 Copyright (c) 2018 The Stdlib Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 19 --> 20 21 # Merge 22 23 > Merge and extend objects. 24 25 <section class="usage"> 26 27 ## Usage 28 29 ```javascript 30 var merge = require( '@stdlib/utils/merge' ); 31 ``` 32 33 #### merge( target, source1\[, source2\[,...,sourceN]] ) 34 35 Merges and extends a target `object`. 36 37 ```javascript 38 var target = { 39 'a': 'beep' 40 }; 41 var source = { 42 'a': 'boop', 43 'b': 'bap' 44 }; 45 46 var out = merge( target, source ); 47 /* returns 48 { 49 'a': 'boop', 50 'b': 'bap' 51 } 52 */ 53 ``` 54 55 The function supports merging multiple source `objects`. 56 57 ```javascript 58 var target = { 59 'a': 'beep' 60 }; 61 var source1 = { 62 'b': 'boop' 63 }; 64 var source2 = { 65 'c': 'cat' 66 }; 67 68 var out = merge( target, source1, source2 ); 69 /* returns 70 { 71 'a': 'beep', 72 'b': 'boop', 73 'c': 'cat' 74 } 75 */ 76 ``` 77 78 #### merge.factory( options ) 79 80 Returns a custom merge `function` for merging and extending `objects`. 81 82 ```javascript 83 var opts = { 84 'level': 100, 85 'copy': true, 86 'override': true, 87 'extend': true 88 }; 89 90 var m = merge.factory( opts ); 91 ``` 92 93 The function accepts the following `options`: 94 95 - **level**: limits the merge depth. The default merge strategy is a deep (recursive) merge. Default: `+infinity`. 96 - **copy**: `boolean` indicating whether to [deep copy][@stdlib/utils/copy] merged values. Deep copying prevents shared references and source `object` mutation. Default: `true`. 97 - **override**: defines the merge strategy. If `true`, source `object` values will **always** override target `object` values. If `false`, source values **never** override target values (useful for adding, but not overwriting, properties). To define a custom merge strategy, provide a `function`. Default: `true`. 98 - **extend**: `boolean` indicating whether new properties can be added to the target `object`. If `false`, only **shared** properties are merged. Default: `true`. 99 100 The default merge is a deep (recursive) merge. 101 102 ```javascript 103 var m = merge.factory( {} ); 104 105 var target = { 106 'a': { 107 'b': { 108 'c': 5 109 }, 110 'd': 'beep' 111 } 112 }; 113 var source = { 114 'a': { 115 'b': { 116 'c': 10 117 } 118 } 119 }; 120 121 var out = m( target, source ); 122 /* returns 123 { 124 'a': { 125 'b': { 126 'c': 10 127 }, 128 'd': 'beep' 129 } 130 } 131 */ 132 ``` 133 134 To limit the merge depth, set the `level` option. 135 136 ```javascript 137 var m = merge.factory({ 138 'level': 2 139 }); 140 141 var target = { 142 '1': { 143 'a': 'beep', 144 '2': { 145 '3': null, 146 'b': [ 5, 6, 7 ] 147 } 148 } 149 }; 150 151 var source = { 152 '1': { 153 'b': 'boop', 154 '2': { 155 '3': [ 1, 2, 3 ] 156 } 157 } 158 }; 159 160 var out = m( target, source ); 161 /* returns 162 { 163 '1': { 164 'a': 'beep', 165 'b': 'boop', 166 '2': { 167 '3': [ 1, 2, 3 ] 168 } 169 } 170 } 171 */ 172 ``` 173 174 By default, merged values are [deep copied][@stdlib/utils/copy]. 175 176 ```javascript 177 var m = merge.factory( {} ); 178 179 var target = { 180 'a': null 181 }; 182 var source = { 183 'a': { 184 'b': [ 1, 2, 3 ] 185 } 186 }; 187 188 var out = m( target, source ); 189 190 console.log( out.a.b === source.a.b ); 191 // => false 192 ``` 193 194 To allow shared references, set the `copy` option to `false`. 195 196 ```javascript 197 var m = merge.factory({ 198 'copy': false 199 }); 200 201 var target = {}; 202 203 var source = { 204 'a': [ 1, 2, 3 ] 205 }; 206 207 var out = m( target, source ); 208 209 var bool = ( out.a === source.a ); 210 // returns true 211 ``` 212 213 To prevent existing properties from being overridden, set the `override` option to `false`. 214 215 ```javascript 216 var m = merge.factory({ 217 'override': false 218 }); 219 220 var target = { 221 'a': 'beep', 222 'b': 'boop' 223 }; 224 225 var source = { 226 'a': null, 227 'c': 'bop' 228 }; 229 230 var out = m( target, source ); 231 /* returns 232 { 233 'a': 'beep', 234 'b': 'boop', 235 'c': 'bop' 236 } 237 */ 238 ``` 239 240 Alternatively, to define a custom merge strategy, set the `override` option to a `function`. 241 242 ```javascript 243 function strategy( a, b, key ) { 244 /* Parameters: 245 a => target value 246 b => source value 247 key => object key 248 */ 249 if ( key === 'a' ) { 250 return b; 251 } 252 if ( key === 'b' ) { 253 return a; 254 } 255 return 'bebop'; 256 } 257 258 var m = merge.factory({ 259 'override': strategy 260 }); 261 262 var target = { 263 'a': 'beep', 264 'b': 'boop', 265 'c': 1234 266 }; 267 268 var source = { 269 'a': null, 270 'b': {}, 271 'c': 'bop' 272 }; 273 274 var out = m( target, source ); 275 /* returns 276 { 277 'a': null, 278 'b': 'boop', 279 'c': 'bebop' 280 } 281 */ 282 ``` 283 284 To prevent non-existent properties from being added to the target `object`, set the `extend` option to `false`. 285 286 ```javascript 287 var m = merge.factory({ 288 'extend': false 289 }); 290 291 var target = { 292 'a': 'beep', 293 'b': 'boop' 294 }; 295 296 var source = { 297 'b': 'hello', 298 'c': 'world' 299 }; 300 301 var out = m( target, source ); 302 /* returns 303 { 304 'a': 'beep', 305 'b': 'hello' 306 } 307 */ 308 ``` 309 310 </section> 311 312 <!-- /.usage --> 313 314 <section class="notes"> 315 316 * * * 317 318 ## Notes 319 320 - The target `object` is **mutated**. 321 322 ```javascript 323 var target = { 324 'a': 'beep' 325 }; 326 var source = { 327 'b': 'boop' 328 }; 329 330 var out = merge( target, source ); 331 332 console.log( out === target ); 333 // => true 334 335 console.log( target.b ); 336 // => 'boop' 337 ``` 338 339 To return a new `object`, provide an empty `object` as the first argument. 340 341 ```javascript 342 var target = { 343 'a': 'beep' 344 }; 345 var source = { 346 'b': 'boop' 347 }; 348 349 var out = merge( {}, target, source ); 350 351 console.log( out === target ); 352 // => false 353 ``` 354 355 - **Only** plain JavaScript `objects` are merged and extended. The following values/types are either [deep copied][@stdlib/utils/copy] or assigned: 356 357 - `Boolean` 358 - `String` 359 - `Number` 360 - `Date` 361 - `RegExp` 362 - `Array` 363 - `Int8Array` 364 - `Uint8Array` 365 - `Uint8ClampedArray` 366 - `Init16Array` 367 - `Uint16Array` 368 - `Int32Array` 369 - `Uint32Array` 370 - `Float32Array` 371 - `Float64Array` 372 - `Buffer` ([Node.js][node-buffer]) 373 - `Set` 374 - `Map` 375 - `Error` 376 - `URIError` 377 - `ReferenceError` 378 - `SyntaxError` 379 - `RangeError` 380 381 - Support for deep merging class instances is inherently [**fragile**][@stdlib/utils/copy]. 382 383 - `Number`, `String`, or `Boolean` objects are merged as [primitives][@stdlib/utils/copy]. 384 385 - Functions are **not** [deep copied][@stdlib/utils/copy]. 386 387 </section> 388 389 <!-- /.notes --> 390 391 <section class="examples"> 392 393 * * * 394 395 ## Examples 396 397 <!-- eslint no-undef: "error" --> 398 399 ```javascript 400 var merge = require( '@stdlib/utils/merge' ); 401 402 var target; 403 var source; 404 var out; 405 406 target = { 407 'a': 'beep', 408 'b': 'boop', 409 'c': { 410 'c1': 'woot', 411 'c2': false, 412 'c3': { 413 'c3a': [ 1, 2 ], 414 'c3b': null 415 } 416 }, 417 'd': [ 1, 2, 3 ] 418 }; 419 420 source = { 421 'b': 3.141592653589793, 422 'c': { 423 'c1': 'bap', 424 'c3': { 425 'c3b': 5, 426 'c3c': 'bop' 427 }, 428 'c4': 1337, 429 'c5': new Date() 430 }, 431 'd': [ 4, 5, 6 ], 432 'e': true 433 }; 434 435 out = merge( {}, target, source ); 436 /* returns 437 { 438 'a': 'beep', 439 'b': 3.141592653589793, 440 'c': { 441 'c1': 'bap', 442 'c2': false, 443 'c3': { 444 'c3a': [ 1, 2 ], 445 'c3b': 5, 446 'c3c': 'bop' 447 }, 448 'c4': 1337, 449 'c5': <Date> 450 }, 451 'd': [ 4, 5, 6 ], 452 'e': true 453 } 454 */ 455 ``` 456 457 </section> 458 459 <!-- /.examples --> 460 461 <section class="links"> 462 463 [@stdlib/utils/copy]: https://www.npmjs.com/package/@stdlib/utils/tree/main/copy 464 465 [node-buffer]: http://nodejs.org/api/buffer.html 466 467 </section> 468 469 <!-- /.links -->