@@ -560,31 +560,51 @@ console.log(newName); // ['Ryan', 'McDermott'];
560
560
** [ ⬆ back to top] ( #table-of-contents ) **
561
561
562
562
### Avoid Side Effects (part 2)
563
- Side effects could also occur from inside a function. In JavaScript, primitives are
564
- passed by value and objects are passed by reference. In the later case, we should be
565
- careful not to change any of these argument's properties.
566
-
567
- A possible solution would be to always clone the variable, edit it and return the
568
- clone. There would be cases where you actually want to modify the input object
569
- and this should not be taken as a silver bullet. Furthermore, cloning big objects can
570
- be very expensive in terms of performance.
563
+ In JavaScript, primitives are passed by value and objects/arrays are passed by
564
+ reference. In the case of objects and arrays, if our function makes a change
565
+ in a shopping cart array, for example, by adding an item to purchase,
566
+ then any other function that uses that ` cart ` array will be affected by this
567
+ addition. That may be great, however it can be bad too. Let's imagine a bad
568
+ situation:
569
+
570
+ The user clicks the "Purchase", button which calls a ` purchase ` function that
571
+ spawns a network request and sends the ` cart ` array to the server. Because
572
+ of a bad network connection, the ` purchase ` function has to keep retrying the
573
+ request. Now, what if in the meantime the user accidentally clicks "Add to Cart"
574
+ button on an item they don't actually want before the network request begins?
575
+ If that happens and the network request begins, then that purchase function
576
+ will send the accidentally added item because it has a reference to a shopping
577
+ cart array that the ` addItemToCart ` function modified by adding an unwanted
578
+ item.
579
+
580
+ A great solution would be for the ` addItemToCart ` to always clone the ` cart ` ,
581
+ edit it, and return the clone. This ensures that no other functions that are
582
+ holding onto a reference of the shopping cart will be affected by any changes.
583
+
584
+ Two caveats to mention to this approach:
585
+ 1 . There might be cases where you actually want to modify the input object,
586
+ but when you adopt this programming practice you will find that those case
587
+ are pretty rare. Most things can be refactored to have no side effects!
588
+ 2 . Cloning big objects can be very expensive in terms of performance. Luckily,
589
+ this isn't a big issue in practice because there are
590
+ [ https://facebook.github.io/immutable-js/ ] (great libraries) that allow
591
+ this kind of programming approach to be fast and not as memory intensive as
592
+ it would be for you to manually clone objects and arrays.
571
593
572
594
** Bad:**
573
595
``` javascript
574
596
const addItemToCart = (cart , item ) => {
575
597
cart .push ({ item, date: Date .now () });
576
-
577
- return cart;
578
598
};
579
599
```
580
600
581
601
** Good:**
582
602
``` javascript
583
603
const addItemToCart = (cart , item ) => {
584
604
const c = Object .assign ({}, cart);
585
-
605
+
586
606
c .push ({ item, date: Date .now () });
587
-
607
+
588
608
return c;
589
609
};
590
610
```
0 commit comments