Check out a free preview of the full The Hard Parts of Object Oriented JavaScript course
The "Creating Objects with Functions" Lesson is part of the full, The Hard Parts of Object Oriented JavaScript course featured in this preview video. Here's what you'd learn in this lesson:
Will diagrams solution 1, a function that returns an object when initiated. It's then explained why the solution wouldn't work in practice.
Transcript from the "Creating Objects with Functions" Lesson
[00:00:00]
>> Speaker 1: Our first solution is just producing these objects that are the perfect representation in our application of our data with the associated functionality. Put that process of creation in a function. Create an object. See the code to add the properties, add the function, and then return that object out into User1.
[00:00:21]
We're gonna end up with exactly the same situation as we had when we hand crafted these objects. But now, we're doing it in a single line. Create user object into User1 with fill and for as the properties. User a two with property. And in both cases, a copy of our increment function on User1.
[00:00:42]
A copy of our increment function on User2. Already, you might spot that there might be some issues with this approach. There might be some challenges. And so, at this point, we are going to start our generation of objects, but now with a function. This approach, folks, easy to reason about.
[00:01:07]
But hard to add features we're gonna see, and fundamentally untenable in terms of whether it's going to be performant in terms of memory.
>> Speaker 1: Let's start off by declaring our function here. Declare the function. That means save in memory the function user creator. Storing the code in the function.
[00:01:32]
Perfect. Next line, Chris.
>> Chris: We're declaring a constant new user as the object.
>> Speaker 1: So you were right to just say we don't run any of the code in user creator until we do what?
>> Chris: You call them.
>> Speaker 1: We call it. So we grab all of that code and we're gonna represent, I'm not gonna write out the code, but think of it all being in here basically.
[00:01:55]
>> Speaker 1: So what actually, Chris, if not the body of the function, is the next line of code that JavaScript executes or does?
>> Chris: Creating a new user, or new constant User1?
>> Speaker 1: Perfect, he's spot on. User1, there it is. User1. And do we know where to store User1 yet?
[00:02:13]
>> Speaker 3: The return of user/creator.
>> Speaker 1: Fantastic, the return value of calling user creator. So User1 is, now const doesn't assign and define to USer1. It's an unmutatable label. You can't change the data, and so it actually remains uninitialized until we go and get the return value from calling User created spawn.
[00:02:38]
So I'm just gonna leave it blank because it's uninitialized. Actually, it's not even declared, but we'll just leave it there for now while we go off and call user creator. User1 is going to be the return value of calling user creator with the input of fill and four.
[00:02:59]
And folk, I'm gonna represent whenever you start running a function in JavaScript. As I say, you need what's called an execution context. Context means space to do something. This is the space in which to execute, to run, that function's code. It comprises the thread of execution, which means we are no longer running code outside that function.
[00:03:21]
We're just running that function's code line by line, threading its way through and executing line by line. And a little mini-memory to save any of the stuff that gets declared inside that function. I'm gonna represent it with this box here. Think of it as a frame in other languages, or similar.
[00:03:37]
Into it we go. And it's got a memory. I'm gonna call it the local memory because it's only available inside this function. Anything return out this function will be deleted, cuz it's local to this function. That just means we're inside the function. Inside the function execution context. In this local memory, the first thing we put in, Seth, are what?
[00:04:02]
>> Seth: Declaring the constant and the user.
>> Speaker 1: That's the second thing, man. What's the very first thing we handle?
>> Seth: The two parameters.
>> Speaker 1: The parameters, exactly. So name is assigned what value?
>> Seth: Fill.
>> Speaker 1: Yeah, not Will. [LAUGH] Recently became less self-centered.
>> Seth: [LAUGH]
>> Speaker 1: And changed it from Will to fill.
[00:04:23]
And score is?
>> Seth: Four.
>> Speaker 1: Four, perfect. New user is then a big old empty object. And let's now populate its properties. And folk, this may feel procedural right now It's gonna get profoundly more complex as we go, but we'll have the foundations down to do so. Nick, throw out the properties for me.
[00:04:49]
>> Nick: First is the name. Name gets assigned. And then, score.
>> Speaker 1: So let's be as clear as possible, if we can, Nick. So we assign, we are dynamically assigning a name property to the newUser constant, or newUser object, and it's gonna have what value?
>> Nick: The name, a key will have the value of fill.
[00:05:09]
>> Speaker 1: Which is our?
>> Nick: String.
>> Speaker 1: Which is our?
>> Nick: Argument.
>> Speaker 1: Yeah, argument. So parameter, name is the parameter. The argument is the one we pass in. So the argument fill is passed in. Perfect. There it is. And then, next according to the same pattern. Chris, go ahead.
[00:05:28]
>> Chris: It's the score argument.
>> Speaker 1: Score argument. Which is?
>> Chris: Four.
>> Speaker 1: Four is assigned to?
>> Chris: The score.
>> Speaker 1: To the score?
>> Chris: Property.
>> Speaker 1: Property, perfect. And then, finally, Michael, what do we add to this object?
>> Nick: Another property called increment.
>> Speaker 1: Increment.
>> Nick: That's declared as a function.
[00:05:47]
>> Speaker 1: Beautiful. Which is on an object known as a method in JavaScript. Okay, there's our perfect object. It's our dream object. It has everything we need on it. All the data representing this using, yes, we've simplified it. It's not 50 properties. And it's got the functionality. Normally, there would be 50 functions, 100 functions.
[00:06:07]
But it's got the functionality we need all bundled on the object. But where is it? It's inside the execution context. So what do we need to do? Was it David? David, what do we need to do to get this object out?
>> Speaker 7: We need to return it.
>> Speaker 1: Return it, perfect.
[00:06:21]
Return it into what global constant?
>> User1
>> Speaker 1: User1. Perfect, there it is. Score four, and increment is a function.
>> Speaker 1: Beautiful. Folk, this has produced an object just like we did manually. We're not gonna go through calling the function again. But I'm gonna walk through it quickly to produce another object so we can see whether our dream is possible.
[00:06:55]
Are we able to call increment to the right-hand side of the dot? We hope so. All right, Michael, talk me through the next line. We're back in the global execution context. We're back into the global, they call it the global execution context. What is the next line of code say to do, Michael?
[00:07:17]
>> Michael: Create another user called User2.
>> Speaker 1: Yeah, or just another object. User2, which is gonna be the return value. Sorry object, another constant would use a two, is going to be the return value of calling.
>> Speaker 9: User creator.
>> Speaker 1: User creator. Okay, so we're not gonna walk through this execution context In detail.
[00:07:38]
So with Julia.
>> Speaker 1: And five. We're not gonna walk through this execution context in detail. But we know it's going to turn out a brand new object with name Julia, score five. And a brand new copy of that increment functionality that was saved. That means it's literally saved in the computer's memory, and we're gonna do the same thing.
[00:08:06]
We're gonna declare a brand new increment function and save it on that object before we return it out.
>> Speaker 1: And there it is, the brand new increment method on that object. But now, we do our check. David, let's do our check together. David, can I do my dream?
[00:08:28]
All I want in my basics of object-oriented programming is that my functionality is available right there on my data. David, can I do that? Can I refer to my functionality to the right-hand side of the dot and hope it works? Walk me through the look up process of JavaScript here, David.
[00:08:50]
So we have User1. Where do we look for it?
>> Speaker 10: In the global memory.
>> Speaker 1: In global memory. Do we find it?
>> Speaker 10: Yes.
>> Speaker 1: We do?
>> Speaker 10: Yes.
>> Speaker 1: And then, what are we looking for on it?
>> Speaker 10: The increment function.
>> Speaker 1: Do we find it?
>> Speaker 10: Yes.
[00:09:02]
>> Speaker 1: Beautiful, we do. We can grab its code and we can execute it. Folk, it may seem trivial, but this is all we really wanna do. This is all we fundamentally want to do. But who can tell me, fast, so we can move on from this terrible approach.
[00:09:20]
Chris, what makes this approach untenable? Can you tell me? What makes this approach such that we could never in practice do this?
>> Speaker 11: You gotta call it on every user?
>> Speaker 1: You got, say that again?
>> Speaker 11: Call it on every user that you wanna create?
>> Speaker 1: Not so much call it on every user.
[00:09:39]
Raise hand if you got an idea. Yes, Seth, go ahead.
>> Seth: The increment method is stored individually on each object.
>> Speaker 1: Exactly. We're doing copies of identical function on every single object. Now, why not? I mean, that's kind of what we want. We wanna be able to refer to that function to be used on that object.
[00:09:55]
I wanna be able to do not just user1.increment, but also user2.increment. I wanna be able to call increment on User2. So I need it to be on User2. But this would be an impossible language design if we had this as the only way of having functions be available to an object.
[00:10:22]
That it had to be stored directly on the object. For now, we have one function. But folk, imagine if we had 100, 200 functions, all of which we want users to have access to.
>> Speaker 1: Decrease score, increase score, increment score. Decrement score, display user, add avatar, login user, authenticate user, logout user.
[00:10:44]
All of these functions would need to be available on every single user so that we could do it to that user as they play our quiz game. So we could easily write code that says where's the function? Don't worry, it's right there on the object.
>> Speaker 1: This approach does serve our purpose.
[00:11:04]
>> Speaker 1: But there must be another way. Now, another language is we have implementations that avoid all of this. But JavaScript does not have object oriented nature of other languages. So who can intuitively tell me, not in terms of OOP and other language implementations, but just what would be an intuitive way?
[00:11:22]
How many copies, David, do we really want of the increment function?
>> Speaker 11: One.
>> Speaker 1: One.
>> Speaker 1: So our dream, perhaps, would be to have one, not have increment on User2, not have it on User500, not have it one User1. But instead, have it somewhere else. And JavaScript's interpreter at the moment at which it tries to make and use increment, not find it on USer1, but not panic.
[00:11:52]
And instead, go and look in this other object full of methods where it finds increment. Perfect.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops