Transcript from the "Don't Mutate, Copy" Lesson
>> Kyle Simpson: So read-only data structures are data structures that never need to be mutated, that's key. A read-only data structure is a data structure that never needs to be mutated ever again. You might create it and do some mutation in its creation process, but at some point, you freeze it, you say it's done, it's final, it's complete.
>> Kyle Simpson: And then you move on. You use that in that final value form for the rest of the program.
>> Kyle Simpson: That actually is, there's a lot of those. There's a lot of times when we create a config object that we're gonna parse in to an Ajax call or something like that.
[00:00:40] That's an object that isn't gonna change or at least it shouldn't otherwise, we're probably gonna have bugs that we don't expect. So that's an example when we pass in an object, when you pass in a configuration array or something like that, you even take a JSON response from an API.
[00:00:56] That's a value that's done. It's come back from the database, it's come back from the API, it's done. It ought to be marked as read-only. Cuz there's no reason for us to be mucking with that in some way that's gonna end up creating a missed expectation and therefore a bug somewhere else in the code.
[00:01:13] Those are all data structures that don't need to be mutated.
>> Kyle Simpson: But that certainly can't be all of our data structures. We certainly can't imagine a program that would do anything useful if all of our data structures were in this read-only state. Some of them, sure, but all of them in a read-only state would mean a program that was fixed and did nothing.
[00:01:38] And we could just delete it and move on.
>> Kyle Simpson: So when I take that processOrder function and I pass in an order to it, you'll notice here that I'm trying to change it. Because I'm doing something that makes sense only for the database. I'm not even thinking about what somebody might have done with that order object after having called me.
[00:02:04] I'm just trying to make sure there's a particular flag on it before I try to save it to the database. You see the mutation there? The mutation that occurs by reference is by definition a side effect, we have an impure function. Of course, we have an impure function because of the database call, but we have another impurity which can create huge bugs in our program.
>> Kyle Simpson: So just because somebody may or may not remember to pass in object.freeze, I have an even more important point to make about this idea of value mutability. Which is if somebody passes you a value, that is in its identity, mutable, something like an array or an object, then it is incumbent upon you, the author of the function.
[00:02:58] You don't know all of the call sites for this function. You don't know whether they're going to pass object.freeze or not. The best thing for you to do is to always assume that it's a read-only data structure. Always assume that you're not allowed to mutate it.
>> Kyle Simpson: Don't assume that because you mutate it and you don't see an error at that point, that nobody else is gonna try to pass in an object.freeze data structure.
[00:03:27] In which case you would have a fatal failure. Always assume that you're not allowed to do line 3, you're not allowed to mutate it. So what do we do? We need to add a status field to it before we save it to the database. The answer is, you make a copy of the object.
[00:03:43] You make a copy of the object which is what I'm doing on line 2. And that copy, I'm simply using the dot dot dot operator, that's object spread. You make a copy of that object, and then you can mutate it internally all that you want. Because you're not having a side effect on the outside program.
>> Kyle Simpson: You should always, always assume that it's a read-only data structure, no matter what. So there's two sides of this issue, and don't lose track of them. One side of the issue is that when you call a function and you're going to pass in a data structure, do your reader the benefit of annotating it that you want it to not be changed.
[00:04:24] Use something like object.freeze. And secondly, and maybe even more importantly, when you write a function that receives data structures, treat it as if it's read-only no matter what. Make a copy of it, make your changes to your local copy.
>> Kyle Simpson: That's how we deal effectively with value mutability.