So we have our user object type created by using a constructor function and the prototype for methods. Now, before, when we work with classes, we touched on class inheritance or subclasses to create that admin class. Now an admin class extended the user class. It inherited all of its properties and methods, but also added its own delete user method too. So how do we achieve that without the use of a class keyword? Well, to create an admin object type, we first need an admin constructor, so let's do that first of all. I'm going to say function admin like so. And then we still need to take in all the same parameters, username and email. So we'll say username and email. And then later, if we wanted to take in a third parameter right here, we could do for now, let's just take in the username and email. So we've taken those parameters in and we could create an admin down here by saying const user three is equal to new admin. And then inside the admin we pass in a name Sean and the email which is going to be Sean at the Net Ninja Ee.co.uk. So we've passed those values in as arguments and we receive those in as parameters right here. But how do we actually set these properties on the admin objects? Well, what we could do is we could just say this dot username is equal to username, much like we did up here like this. Again, what? That kind of defeats the whole idea of inheritance. And it means we're duplicating our code now when we use classes. What we did was use a function called super and that function called the constructor of the parent class. But without classes we don't have access to this super function. We can't do that. We need a different way to do that. So we need to somehow call the user constructor up here and pass in our parameters, username and email. Now we can't just say something like new user in here and pass in the parameters username and email because that is going to create a brand new object to do this. And we already have a new object when we created the new admin. So we can't do that. We need a different way to do it. So somehow we need to be able to call the user constructor and pass in the new blank object that we created when we said new admin. So then inside the user constructor we can attach properties to it. Now the way we do this is by using a method on the user constructor function called Call. So I can say user dot call and that is going to call this constructor. Now we pass in a few different arguments into this call method. The first argument is going to be the context of what the this keyword will be equal to inside the user constructor function. Now we want the this keyword inside here when we call it from the admin to be the new object that we just created when we say new admin now inside the admin function that is just this. So we can pass in this as the first argument to refer to the object we just created. Then when we call user this inside the user constructor is going to be equal to whatever we pass in, which is the new object that we created when we said new admin. Therefore, when we attach properties to it, we're attaching them to that new object, which is the thing we need to do. So that's the first argument. The next arguments are the actual parameters that we need to take in. So for example, we need to pass in the username and the email so we can pass in these things right here so we can say username and then email and they're going to match up to the first and second. So when we call the user constructor function, it's going to run passing the context of whatever. We want this to be inside the constructor, then it's going to pass in the actual parameters that we need to take in. And it's going to set the username and password on the new object we just created right here. So that is pretty much doing the same as the super function did before when we used classes. So now if I log out user three down here like this and save it, then we should see now we have user three which is an admin. The username and email, they are attached to the object. So this has worked. So now if we wanted to add additional properties only to admin objects and not users, we could do that inside the admin constructor. So I could come down here and say, okay, well this now dot title is equal to the title and now admins will have this title property. We need to take that in as a parameter and also pass it in as an argument when we create a new admin. So let's do that. This will be Black Belt Ninja if I save this now and view it over here. Now we can see that the admin has this title property, but users don't have this title property because we don't define it inside the user constructor only in the admin constructor. So that's how we inherit all the different properties and add our own properties now to the admin. But what about the functions or the methods? Because we also attach these methods to the user prototype. So all users have these methods, but admins at the minute they don't have any methods. An admin has its own prototype, which I'm going to log to the console or just rather say admin dot prototype in the console and we can see in here we don't have access to any methods except this constructor, which is this thing. So what we need to do is somehow figure out a way that our admin objects can inherit the methods on the user prototype. So essentially what we need to do is copy the user prototype to the admin prototype. So then the admin prototype is getting all of those methods. Now the way we do this is by coming down here and saying admin dot prototype and setting that equal to something. Now what we want to do is create a new object and base that object on the user prototype. We're essentially copying it then so we can create a new object by saying object. That's the object constructor. Then using a method called create. And this creates a brand new object. Now, inside as an argument, we can pass in the user prototype like this, and then it creates an object and bases it on the user prototype. So now we have essentially a copy of the user prototype in the admin prototype. So now if I save this and come down here and say admin dot prototype, we can see inside, then we get all these methods. Now if I just expand the admin object that we created, we can see inside this prototype that it points to the user that's saying, Look, you're inheriting stuff from the user and if we expand this, then inside the second proto, that is where we get access to the methods. So it's kind of two levels deep in the proto, which means we're inheriting. Now if I come and add one directly to the admin prototype, it would be in the first level, not in the second level where we inherit from the user. So if I now say admin dot prototype and then add a new method and I'm going to call this delete user, set it equal to a function and this function does something inside, we'll just say delete a user. We won't write this out, but essentially we're adding this new method now to the admin prototype, but not the object. Now if we save this and open up this admin, we can see inside here proto points to user. We have a delete user on the admin prototype itself, but also we inherit these ones in the second proto from the user. So we have this little chain of nested proto properties to represent this inheritance. And if we were to add another object type like super admin which inherited from the admin, we'd see three nested proto props here instead. And this is called the prototype chain and it's the underlying architecture of Prototypal inheritance. This is the stuff that's going on under the hood when we use the class keyword and extend a class to make a subclass. So that's prototypal inheritance. The inner workings of how classes are made and extended in JavaScript. Now a lot of the time you won't be using this type of work and you might just opt to use JavaScript classes instead. But I think understanding this concept of what's actually happening when we create classes is very useful to know, especially when it comes to writing more complex applications, debugging code and even working with other developers code, because not everyone will always use the class syntax. Some developers prefer to use the. Prototype inheritance model. So again, just quickly, we first of all used user dot call and called the user constructor. That way we apply all of the properties inside the user constructor to our new object. When we create a new admin, then we can add extra properties inside the admin constructor just for admin objects. Then we want to inherit the user prototype methods. So we said admin dot prototype is equal to object.create to create a new object, then base it on the user prototype. So now we're inheriting these methods from the user prototype onto the admin prototype. Then we're adding a new method delete user just to the admin prototype. So then admins will have access to this, but users won't. And that, my friends, is the Prototypal inheritance model.