Now, if we close that, and look at our child object,
you could see that it doesn't really have any properties of its own.
But if we open it up, you'll see that it has one special property called
__proto__ and it's a special property you shouldn't be accessing directly for
performance reasons.
But that is where the JavaScript engine, in its kind of behind the scenes
holds a reference to the parent prototype of the child object.
So if you open that up, you'll see that it looks very familiar.
It's got the obj property, the value property, and
the walk property, which is a function.
So you can see that we're still referencing our parent object
using this __proto__ property.
Let's go back to the code editor and
we'll uncomment the next chunk of code, which is the one right here.
And what we're going to do now is, we're actually going to declare our own
value property on the child object and we'll call it childValue.
And we'll also say child.obj.objValue and change the value to childObjValue.
Now what should happen here is since we're declaring a value property on the child,
when we reference it later in the console.log,
the JavaScript engine will not access the parent's value property.
But it will access the child's value property because
the child's value property Is masking the parent value property.
However, since this obj property is still not a property of the child object.
But it's still requiring the JavaScript engine
to walk up the prototype chain in order to look it up.
This obj value will actually get changed and
changed to the string child objValue on the parent object itself.
So what we're going to do is we're going to declare that we changed stuff.
I'm going to actually just copy and
paste these lines of code right in the console.log, so
we could see what we're changing in our console in the browser.
And then we'll again, go ahead and log the child, child.value, child.objValue and
we'll log parent.value, and we'll log parent.obj.objValue.
And if everything works right, the parent.obj.objValue should be
equal at this point to whatever comes out from child.obj.objValue.
They should really point to the same object, and then for
good measure we will go ahead and output the parent object and the child object.
Let's go ahead and save that, go to our browser.
And we could see after we changed things, we changed the child value to
childValue and now this value is masking our prototype's parentValue property.
So if we go to the child, we'll see it will indeed say childValue as we set it,
and if we go to the parent.
You could see that the parent did not get changed simply because we
are masking the value now in the child.
And we're not affecting the parentValue when we're setting it right here
to this string childValue.
However, since when we access or set the objValue,
which is itself a property of the obj property.
That obj property requires the JavaScript engine to walk up the prototype chain and
look it up on the parent object.
And therefore, when we change it,
this string will now get recorded in the parent.obj.objValue directly.
And now, if you look at our objects that we actually output to the console,
you'll see that our child object now has its own value called childValue.
And if we open it up, you'll see it doesn't need to have a childValue, and
its __proto__ or prototype is still pointing to the parent.
And the parent has a value, but its value is still saying parentValue.
Again, that's because the value got
masked by the child property that is of the same name.
Let's go back to the code editor and actually verify that the child,
let's uncomment this slide right here, and
verify that the child obj is actually equal to the parent obj.
Meaning that when we resolve the .obj on the child,
the JavaScript engine actually walks up the prototype chain.
And it is the exact same instance of the object that is attached to the parent one.
So we'll go ahead and say if one equals the other it should output true,
we'll save this, we'll go back to the browser and
indeed, child.obj is actually equal to the parent.obj.
Okay, so let's go back to the code editor once again and
let's see here that we don't have to get stuck on just one child.
We could create a grandchild of the parent and the way we could do that is yet again,
call Object.create except this time our prototype will be the child.
Which means the grandchild is create based on the prototype of the child object, and
the child object is still an object that was based on the parent object.
So therefore, the grandchild and you can tell that this is still working just fine,
because we can first of all output it to the console and
see what that object holds.
And certainly, we can call grandChild.walk, which is something that
is not even coming from the child object but coming all the way from the parent.
Let's go ahead and save that, let's go back to our browser console and
you see here that the Grandchild object is an empty one.
But if we open it up you see we have a prototype.
Open that up, that prototype, which is our child object has its own child value,
or the value property with child value as the string.
But it also has a prototype as well, if we open that up,
you'll see our familiar parent object with its walk method.
And sure enough, when we call Grandchild.walk, it will print
out walking, because this function is console logging the walking!string.
So that's prototypal inheritance and it's really very simple.
It's either the JavaScript engine will look for a property by walking up its
prototype chain and looking on its parent objects for that particular property.
Or if the object already has that property, that property is really masking
the prototype's property, and therefore get resolved immediately.
So as you've seen there's a bit of a contrast here between a primitive value
like a string that gets inherited through the prototypal inheritance.
And the property that is itself an object and
gets inherited through the prototypal inheritance.
The obvious difference here is that changing the values of the properties of
the inherited object does not match those properties from the parent prototype.
Let's go back to the code editor and see one more very important concept
before we jump into the controller as syntax explanation.
In fact, let's go ahead and comment this whole thing out so you can have it for
reference.