Check out a free preview of the full The Good Parts of JavaScript and the Web course:
The "Building a Better Constructor" Lesson is part of the full, The Good Parts of JavaScript and the Web course featured in this preview video. Here's what you'd learn in this lesson:

Doug takes a brief break from the function challenges to explain how to create a better constructor. He starts with a pattern he’s previously shown where a function is used to construct objects. He then revises the pattern to incorporate some ES6 syntax and make the code more secure and reliable.

Get Unlimited Access Now

Transcript from the "Building a Better Constructor" Lesson

[00:00:00]
>> [MUSIC]

[00:00:03]
>> Douglas Crockford: This pattern for using functions to construct objects. And I've got my constructor function, I've passed in my initialization object, I'm calling another constructor, which allows me to inherit what that thing does. And I'm gonna add stuff to that, or that will be the object that I'm constructing.

[00:00:23] I will create my member variables, which are the things that my methods will have access to. That's where I'm gonna be keeping all of the state, all of the data that's within this object. I will create my member methods, which are just local functions within this scope, and each of these will close over the initialization value that we passed in, or whatever that is.

[00:00:44] I recommend an object, over all of the other members and over all of the other methods. So that we don't ever use this in this pattern. And then anything which needs to be public, I publish it by assigning it to the outgoing object and when I'm done, I return the outgoing object.

[00:01:07] And also, have as many members as I want, as many methods as I want. I make as many of them public as I need to, and then I'm done. It's a really straightforward way of making objects, it's very flexible. There are lots and lots of variations on this, but this is the basic pattern that I recommend for using, for constructing objects in JavaScript.

[00:01:30] Now, next year when all of ES6 becomes available, and there's some new syntax in ES6, which can be applied toward this, and also with an eye on making our systems even more secure, I'm going to revise the pattern to be like this. So this is next year's pattern.

[00:01:49] I'm gonna start with a constructor object as before, which will contain lots of good stuff, which tells me how to make the object. Then I'm gonna make my instance variables, and I'm using some new syntax here. First off, I'm using the let statement. In this case, there's no advantage to using let over var, but it makes the Java guys happier, so I'm gonna try to use let as we move to the new language.

[00:02:18] And the curly braces around the variable name, means something special here. So what I'm doing is, I'm creating a new variable called member, and I'm going to initialize it with spec.member. So it's a shorthand for doing those sorts of things, and I can put as many names in the curly braces as I want, separated by commas, and each of those names will be initialized by a similarly named property from that object.

[00:02:48] So this doesn't let us do anything that we couldn't do before, but it's some convenient syntax for pulling values out of the initialization object and putting them into our local variables.
>> Speaker 2: When you say let (member) = spec, now spec.member is initialized?
>> Douglas Crockford: It's the initialization value for the member variable.

[00:03:15]
>> Douglas Crockford: So that statement means the same thing as let (member) = spec.member
>> Speaker 2: Member equals spec.member.
>> Douglas Crockford: Then, I'm gonna use the new const statement. In a similar way, I'm going to this other constructor where I'm going to get methods, which I'm gonna be using, and I'm going to extract the methods that I want to use and put them into private variables.

[00:03:48] And I'm doing that, because I anticipate that this object could be frozen, and so I don't want to be adding stuff to it as I was in the previous model. Because I don't want to break if someone that I'm trying to inherit from passes me as a frozen object.

[00:04:07] This also solves what's sometimes called the banana problem. That there's a complaint about object systems, where you want to inherit a banana. But you end up also inheriting the gorilla that's holding the banana and the jungle that the gorilla is and you get all of this stuff and all you wanted was this little thing.

[00:04:26] So this allows us to do that we can extract things that we want. And because we're extracting things now, we can call it as many of these guys as we want. So we can get to as many of these other constructors and take all of their goodness and pull it out into local variables and we get all that goodness.

[00:04:45] Then, again I'm going to be making my methods, and again my methods will close over all of the stuff. And again, my methods are not using this. Then when I'm done, I publish the public methods here. The ones that I made or the ones that I inherited. And I'm taking advantage of new object literal syntax here.

[00:05:08] That if you have an object literal and you just say a name and you leave out the colon, it's a shorthand for name call a name. So this is short for method called, method. And that's short for other call an other. Again, not essential. But it's nice and it gives us a, this starts to look more like a declaration than like code, where I'm just getting the list of things that I want to publish.

[00:05:38] Then finally, I'm going to freeze that object because freezing gives us very good security and reliability properties for objects, which we can't get in this language in any other way. So when we look at the evolution of programming. In languages like C and Pascal, we've got struct and records.

[00:06:01] Tailored structures which let you have names, properties. And then an object [INAUDIBLE] programming, we took it a step further where we could have functions or methods which are related to those structures which will act upon them. And I think that was a really important evolutionary step, but it shouldn't have been the last step.

[00:06:22] So I think JavaScript actually gives us a way to go forward from this, so that I'm now thinking that we have two very distinct kinds of objects. We have objects which just contain data, only data and objects contain only functions, which are frozen. And those objects are very strong, very reliable that cannot be tampered with.

[00:06:48] They provide the interface for dealing with the objects, which are containing the data. And that way we can create good API's, which can defend themselves. Which can remain robust and in the face of all the confusion that's happening inside of our system.
>> Speaker 2: So how would you pair those two things, the data, object again?

[00:07:09]
>> Douglas Crockford: I'm going to put the data in the member variables.
>> Douglas Crockford: All of the data goes in the member variables, and those could contain simple values like numbers and strings. They could contain objects.
>> Douglas Crockford: So any other questions about that?
>> Speaker 2: I don't understand any of this.
>> Douglas Crockford: Yeah, we'll review it again this afternoon.

[00:07:41] So what I want to do now. Do we need a break or are we ready to go on to the next problem?
>> Speaker 3: Can I just ask a question [INAUDIBLE].
>> Douglas Crockford: Please.
>> Speaker 3: So you're gonna use that pattern. You'll have your function object, you'll have your data object that you'll feed your data into and you'll feed your data object into the function object, act on that function object creating a new data object to then act on.

[00:08:04] The next in the cheat of function objects that are all functions which never change are immutable but they'll create new data sets.
>> Douglas Crockford: Right. Each time we call this constructor, we get a new thing and with it, it's functions go. It will close over, whatever objects you need to work on.

[00:08:22]
>> Speaker 3: In itself and it's data that you were to create, it is all beautiful and it's going to give you new information out of.
>> Douglas Crockford: The data is mutable but only within the function scope, you cannot mutate it from outside, except through the box.
>> Speaker 3: So freeze doesn't mean that you can change its own if you add up the functions.

[00:08:43]
>> Douglas Crockford: Right.
>> Speaker 3: [CROSSTALK] to give a new input.
>> Douglas Crockford: Freeze is only on the object containing the functions. The functions themselves are still free to act on anything with a close.
>> Speaker 3: Okay. To just catch up to you.
>> Speaker 2: Could you go back to the previous slide, please.

[00:09:12]
>> Speaker 2: And it could be five and it could be.
>> Douglas Crockford: Yeah, but that's
>> Speaker 2: It could be anything you want.
>> Douglas Crockford: It's anything you want to pass to a constructor.
>> Speaker 2: I think I'm confused by the fact that
>> Speaker 2: What is the other constructor do if creates a not yet another object that.

[00:10:05]
>> Douglas Crockford: Right. If provides a means of inheriting something else. This is how you would do inheritance in this matter. If you don't need to inherit from something else, then just start without being an empty object.
>> Speaker 2: Or could be some values that you could assign?
>> Douglas Crockford: Whatever, yeah.

[00:10:27]
>> Speaker 2: I don't understand how this is related to you, to work. You congratulated us for doing something five minutes ago that, I've been doing that with a node for a year. And this still doesn't make any sense to, I mean, this makes sense to me. I don't understand the relationship, what we are passing, we are passing a function in-

[00:10:46]
>> Douglas Crockford: The relationship is, this is only possible if you understand how to use closure and function scope. [SOUND] Which is something you can do now.
>> Speaker 2: All right.