@@ -560,31 +560,51 @@ console.log(newName); // ['Ryan', 'McDermott'];
560560** [ ⬆ back to top] ( #table-of-contents ) **
561561
562562### 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.
571593
572594** Bad:**
573595``` javascript
574596const addItemToCart = (cart , item ) => {
575597 cart .push ({ item, date: Date .now () });
576-
577- return cart;
578598};
579599```
580600
581601** Good:**
582602``` javascript
583603const addItemToCart = (cart , item ) => {
584604 const c = Object .assign ({}, cart);
585-
605+
586606 c .push ({ item, date: Date .now () });
587-
607+
588608 return c;
589609};
590610```
0 commit comments