A function’s
prototype
property becomes important when you create a new instance
with the
new
keyword: the newly created object has access to its constructor’s
prototype
object. The object instance stores this in its
__proto__
property.
The __proto__ property is considered part of JavaScript’s plumb‐
ing—as is any property that’s surrounded by double underscores.
You can do some very, very wicked things with these properties.
Occasionally, there is a clever and valid use for them, but until you
have a thorough understanding of JavaScript, I highly recommend
you look at but don’t touch these properties.
What’s important about the prototype is a mechanism called dynamic dispatch (“dis‐
patch” is another word for method invocation). When you attempt to access a prop‐
erty or method on an object, if it doesn’t exist, JavaScript checks the object’s prototype
to see if it exists there. Because all instances of a given class share the same prototype,
if there is a property or method on the prototype, all instances of that class have
access to that property or method.
Setting data properties in a class’s prototype is generally not done.
All instances share that property’s value, but if that value is set on
any instance, it’s set on that instance—not on the prototype, which
can lead to confusion and bugs. If you need instances to have initial
data values, it’s better to set them in the constructor.
Note that defining a method or property on an instance will override the version in
the prototype; remember that JavaScript first checks the instance before checking the
prototype. Let’s see all of this in action:
// class Car as defined previously, with shift method
const
car1
=
new
Car
();
const
car2
=
new
Car
();
car1
.
shift
===
Car
.
prototype
.
shift
;
// true
car1
.
shift
(
'D'
);
car1
.
shift
(
'd'
);
// error
car1
.
userGear
;
// 'D'
car1
.
shift
===
car2
.
shift
// true
car1
.
shift
=
function
(
gear
) {
this
.
userGear
=
gear
.
toUpperCase
(); }
car1
.
shift
===
Car
.
prototype
.
shift
;
// false
car1
.
shift
===
car2
.
shift
;
// false
car1
.
shift
(
'd'
);
car1
.
userGear
;
// 'D'
This example clearly demonstrates the way JavaScript performs dynamic dispatch.
Initially, the object
car1
doesn’t have a method
shift
, but when you call
car1.shift('D')
, JavaScript looks at the prototype for
car1
and finds a method of
154 | Chapter 9: Objects and Object-Oriented Programming