Javascript Prototype: Prototype Chain and Shadowing
Tags: webdev, javascript, prototype, beginners
Published: 2022-12-24 10:00:00

In [part 1](https://dev.to/jessewei/javascript-prototype-the-basics-3n16) of the series, we learned the basics of Javascript prototype. We saw why it is important to understand it, what a prototype really is and looked at some relevant terms.

In this part, we'll continue our journey by diving a bit deeper into prototype and have a look at what _prototype chain_  and _property shadowing_ are.

## Table of Contents

- [Prototype Chain](#prototype-chain)
- [Property Shadowing](#property-shadowing)
- [Conclusion](#conclusion)

---

## Prototype Chain

Every object in JavaScript has a prototype, which is **either an object itself or null**. When a property or method is accessed on an object, JavaScript will first look for that property on the object itself. If it is not found, it will search its prototype. This continues until the property is found or the uppermost prototype, which is _null_, is reached. This process is called prototype chain.

As an example, let's say we have the following code:

```javascript
let vehicle = {
  run() {
    return 'run, run, run!'
  }
}
let car = {
  drive() {
    return 'drive, drive, drive!'
  }
}
let myCar = {
  broken: true
}

myCar.drive() // TypeError: myCar.drive is not a function
myCar.run() // TypeError: myCar.run is not a function
```

When we try to access the `drive()` and `run()` methods on `myCar`, we get an error. This is no surprise, as `myCar` does not have these methods defined on it.

Let's add the following code before calling the methods:

```javascript
...
Object.setPrototypeOf(car, vehicle) // add this
Object.setPrototypeOf(myCar, car) // and this

myCar.drive() // => 'drive, drive, drive!'
myCar.run() // => 'run, run, run!'
```

Now the errors are gone and we get the expected results from calling the methods. But wait, `myCar` still does not have these methods defined on it, does it? 

Because we set the prototype of `car` to `vehicle` and the prototype of `myCar` to `car`, now when Javascript does not find the method `drive()` on `myCar`, it traverses up to its prototype (`car`) where it finds and calls the method. This is prototype chain in action and Javascript follows the chain to find and call `run()` too.


![Prototype chain](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ialb6ng0ddxb664ikcyt.png)

<figcaption>Prototype chain</figcaption>
<br>

Please note that the image above does not show the full story. The prototype chain can actually go even further beyond `vehicle` until it reaches _null_.

![full prototype chain](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fxjkyfmfpnero89smr7s.png)

<figcaption>Full prototype chain</figcaption>
<br>

Near the top of the chain we have `Object.prototype` which is itself an object with methods like `hasOwnProperty`, `toString` and `valueOf`. As any objects down the chain inherit these methods, we can access these methods on `vehicle`, `car` and `myCar`.

For example,

```javascript
myCar.hasOwnProperty('broken') // => true
myCar.hasOwnProperty('drive') // => false
```

Please note that setting the prototype of an object with `Object.setPrototypeOf()` is slow as explained [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf). Instead, it's recommended we create new objects with the desired prototype using `Object.create()`.

```javascript
const myNewCar = Object.create(car)
Object.getPrototypeOf(myNewCar) === car // => true
```

---

## Property Shadowing

Property shadowing sounds abstract and daunting but it is actually a very simple concept. It basically **describes what happens when an object and its prototype both define a property with the same name**.

Because in a prototype chain the object is traversed before its prototype, we know the property defined on the object itself will be accessed or called (in case of a function) before Javascript reaches its prototype.

Considering the previous example after the prototype of `myCar` is set to `car`:

```javascript
car = {
  drive() { // body of drive method },
  price: 100000 // add this
}
myCar = {
  broken: true,
  price: 50000 // add this
}
myCar.price // => 50000
```

In this case, we say the `price` on `myCar` _shadowed_ the `price` property on the prototype of `myCar`.

---

## Conclusion

In this part of the series, we looked at how prototype chain works and what property shadowing is.

If you followed along, you should've had a pretty solid idea on Javascript prototype. But there's just much more about it and in the next part, let's explore concepts like _constructors, classes and inheritance_ which are all built upon the concept of prototype.