# Prototypes and Inheritance

JavaScript is a prototype-based language, meaning that objects can inherit properties and methods from other objects. This is different from class-based inheritance found in languages like Java or C++.

## 1. The Prototype Chain

Every JavaScript object has a special hidden property, `[[Prototype]]` (often exposed as `__proto__` in browsers), which is either `null` or references another object. That object is called "a prototype".

When you try to access a property of an object:
1.  The engine searches the object itself.
2.  If not found, it searches the object's prototype.
3.  If not found, it searches the prototype's prototype.
4.  This continues until the end of the chain is reached (usually `Object.prototype`, whose prototype is `null`).

```javascript
const animal = {
  eats: true,
  walk() {
    console.log("Animal walks");
  }
};

const rabbit = {
  jumps: true
};

// Set rabbit's prototype to animal
rabbit.__proto__ = animal;

// rabbit can now use properties from animal
console.log(rabbit.eats); // true
rabbit.walk(); // "Animal walks"
```

## 2. `F.prototype`

When you create objects using a constructor function (using `new`), the `prototype` property of that function determines the prototype of the created object.

```javascript
function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}`);
};

const john = new Person("John");
john.sayHello(); // "Hello, my name is John"

// john.__proto__ === Person.prototype
```

## 3. `Object.create()`

The modern way to create an object with a specific prototype is `Object.create()`.

```javascript
const animal = {
  eats: true
};

const rabbit = Object.create(animal);
rabbit.jumps = true;

console.log(rabbit.eats); // true
```

## 4. Classes (ES6)

ES6 introduced the `class` keyword, but it is primarily syntactic sugar over the existing prototype-based inheritance.

```javascript
class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name} barks.`);
  }
}

const d = new Dog('Mitzie');
d.speak(); // "Mitzie barks."
```

Under the hood, `Dog.prototype` inherits from `Animal.prototype`.

[[programming/javascript/vanilla/javascript]]
[[programming/javascript/vanilla/es6-features]]