# JavaScript Prototypes

Ever caught yourself typing something like `[1,2,3].map()` and suddenly wondered, where the hell does `map` actually live? You never defined it. It's not sitting there in your array. But it works anyway, every single time.

## **The Hidden Link Every Object Carries**

Here's the part they don't teach clearly every object in JavaScript has a secret connection to another object. Behind the scenes, there's an internal link called `[[Prototype]]`. You can't touch it directly, but you can peek at it.

```javascript
const user = { name: "Chirag" };
console.log(Object.getPrototypeOf(user));
```

There's also this old, informal way. The point is thi when JavaScript looks for a property on `user` and doesn't find it, it doesn't give up. It follows that hidden link upward. It checks the next object. And the next. This chain lookup is the engine that makes JavaScript inheritance work.

## **Following the Chain**

Let's trace what actually happens when you run `user.toString()`.

First, JavaScript checks `user` itself. No `toString` there. So it hops up to `user.__proto__`, which points to `Object.prototype`. `toString` lives there. If it hadn't found it? It would keep climbing. The chain goes: `user` - `Object.prototype` -`null`. `null` means stop. End of the road. If the property isn't found by then, you get `undefined`.

## **The Part Where Functions Get Weird**

Okay, here's where people usually get lost. Functions in JavaScript have a `prototype` property. But that's **not** the same as `__proto__`.

```javascript
function User(name) {
  this.name = name;
}

User.prototype.sayHello = function () {
  return `Hello ${this.name}`;
};

const u1 = new User("Arpit");
console.log(u1.sayHello()); 

// "Hello Arpit"
```

What does `new` actually do? Four things creates an empty object, links its `__proto__` to `User.prototype`, binds `this` to that new object, and returns it. That's it. The `User.prototype` object becomes the prototype for every instance you create. So `u1` doesn't carry `sayHello` around in its pocket. It borrows it from `User.prototype`. One method, shared across every user. That's the memory efficiency people talk about.

ES6 gave us the `class` keyword, and it looks clean -

```javascript
class User {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    return `Hello ${this.name}`;
  }
}
```

## **Why Any of This Actually Matters**

In real systems, prototypes aren't academic trivia. They're practical tools with real consequences.

**Memory efficiency first -** When you put methods on a prototype, every instance shares one function object. Put them in the constructor with `this.method` and you're duplicating that function for every single instance. At scale this is what matters(a lot )

**Performance next -** Deep prototype chains slow down property lookup. If your object inherits from something that inherits from something else, JavaScript has to climb more links. Usually negligible, but worth knowing if you're optimizing hot paths.

## **The Takeaway**

Prototypes aren't some dusty JavaScript quirk. They're the living mechanism behind every method call, every inheritance chain, every `class` you write. Objects delegate upward. The chain ends at `null`. Functions have a `prototype` property that becomes the `__proto__` of their instances.
