# Understanding the new Keyword in JavaScript: Object Creation Under the Hood

> Every time you write `new SomeFunction()`, JavaScript quietly does four things behind the scenes. This article pulls back the curtain — step by step, diagram by diagram.

* * *

## What Does `new` Actually Do?

JavaScript is not a class-based language at its core. Beneath the `class` syntax sugar introduced in ES6 lies a prototype-based system where objects inherit directly from other objects. The `new` keyword is the bridge between *constructor functions* and *object instances*, and understanding it unlocks how JavaScript's inheritance model truly works.

When you invoke a function with `new`, JavaScript performs these four steps automatically:

1.  **Creates a brand-new empty object** `{}`
    
2.  **Sets the prototype** — links the new object's internal `[[Prototype]]` to the constructor's `.prototype` property
    
3.  **Binds** `this` — runs the constructor function with `this` pointing to the new object
    
4.  **Returns the new object** — unless the constructor explicitly returns a different object
    

* * *

## Constructor Functions

A **constructor function** is a regular JavaScript function — with one convention: it is meant to be called with `new`, and its name starts with a capital letter (by community convention).

```js
function Person(name, age) {
  this.name = name;
  this.age  = age;
}
```

Without `new`, calling `Person("Alice", 30)` would run the function normally, and `this` would be the global object (sloppy mode) or `undefined` (strict mode).

With `new`, everything changes:

```js
const alice = new Person("Alice", 30);

console.log(alice.name); // "Alice"
console.log(alice.age);  // 30
```

* * *

## The Object Creation Process, Step by Step

### Diagram — Constructor → Instance Creation Flow

![](https://cdn.hashnode.com/uploads/covers/6963d0f597a4645cf6bed3e0/e84867d7-78db-4585-94f4-0aa1ba4cd8ef.svg align="center")

### Step 1 — A blank object is born

```js
// JavaScript does this internally:
const obj = Object.create(Person.prototype);
```

### Step 2 — The prototype chain is linked

The new object's `[[Prototype]]` slot is pointed at `Person.prototype`. This is what makes the object an *instance* of `Person`.

```js
Object.getPrototypeOf(alice) === Person.prototype; // true
alice instanceof Person;                           // true
```

### Step 3 — The constructor runs with `this` = new object

```js
// Inside the constructor, this === obj (the new empty object)
this.name = "Alice"; // obj.name = "Alice"
this.age  = 30;      // obj.age  = 30
```

### Step 4 — The object is returned

Unless `Person` explicitly returns another *object*, JavaScript returns `this` automatically. No `return` statement needed.

> **Edge case:** If a constructor returns a primitive, JavaScript ignores it and still returns `this`. If it returns a plain object `{}`, *that* object is returned instead and your constructed instance is discarded.

* * *

## How `new` Links Prototypes

Every function automatically gets a `.prototype` property. Methods added to it are *shared* across all instances — never copied.

```js
function Person(name, age) {
  this.name = name;
  this.age  = age;
}

Person.prototype.greet = function () {
  return `Hi, I'm ${this.name} and I'm ${this.age} years old.`;
};

const alice = new Person("Alice", 30);
const bob   = new Person("Bob",   25);

console.log(alice.greet()); // "Hi, I'm Alice and I'm 30 years old."
console.log(bob.greet());   // "Hi, I'm Bob and I'm 25 years old."

// Both instances share the SAME function — not copied
console.log(alice.greet === bob.greet); // true
```

When you call `alice.greet()`, JavaScript traverses the chain:

1.  Does `alice` own `greet`? **No.**
    
2.  Does `Person.prototype` own `greet`? **Yes — found it.**
    

* * *

## Instances Created from Constructors

```js
console.log(alice instanceof Person); // true
console.log(alice instanceof Object); // true (everything is!)
console.log(alice instanceof Array);  // false
```

### Own properties vs. prototype properties

| Property | Belongs to | `hasOwnProperty` |
| --- | --- | --- |
| `name`, `age` | The instance | `true` |
| `greet` | `Person.prototype` | `false` |
| `toString`, `hasOwnProperty` | `Object.prototype` | `false` |

**Per-instance data lives on the instance; shared behaviour lives on the prototype.**

* * *

## Simulating `new` Yourself

```js
function myNew(Constructor, ...args) {
  // Steps 1 & 2: create object and link prototype
  const obj = Object.create(Constructor.prototype);

  // Step 3: run the constructor with this = obj
  const result = Constructor.apply(obj, args);

  // Step 4: return the new object (or constructor's explicit object return)
  return result instanceof Object ? result : obj;
}

const charlie = myNew(Person, "Charlie", 28);
console.log(charlie.greet());           // "Hi, I'm Charlie and I'm 28 years old."
console.log(charlie instanceof Person); // true
```

* * *

## `new` with ES6 Classes

ES6 `class` syntax is *syntactic sugar* — JavaScript compiles it to the same constructor + prototype pattern under the hood.

```js
class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    return `${this.name} makes a sound.`;
  }
}

const dog = new Animal("Rex");
console.log(dog.speak());           // "Rex makes a sound."
console.log(typeof Animal);         // "function" — still a function!
console.log(dog instanceof Animal); // true
```

The `speak` method lives on `Animal.prototype`, not on `dog`. The only practical difference from a plain constructor: calling a `class` without `new` throws a `TypeError`. Constructor functions have no such guard.

* * *

## Common Mistakes

**Forgetting** `new`

```js
const oops = Person("Dave", 40); // no new!
console.log(oops);        // undefined
console.log(window.name); // "Dave" — leaked to the global object
```

**Replacing the prototype after creating instances**

```js
Person.prototype = { greet() { return "hello"; } }; // replaces the object!
alice.greet(); // TypeError — alice still points to the OLD prototype
```

**Arrow functions can't be constructors**

```js
const Broken = (name) => { this.name = name; };
new Broken("x"); // TypeError: Broken is not a constructor
```

* * *

## Quick Reference

```js
// 1. Define a constructor
function Car(make, model) {
  this.make  = make;
  this.model = model;
}

// 2. Add shared methods
Car.prototype.describe = function () {
  return `${this.make} ${this.model}`;
};

// 3. Create instances
const car1 = new Car("Toyota", "Camry");
const car2 = new Car("Honda",  "Civic");

// 4. Verify prototype links
Object.getPrototypeOf(car1) === Car.prototype; // true
car1.describe === car2.describe;               // true — shared!
car1.hasOwnProperty("make");                   // true  — own property
car1.hasOwnProperty("describe");               // false — inherited
```

* * *

## Key Takeaways

*   `new` runs four implicit steps: create object → link prototype → bind `this` → return object
    
*   Methods on `Constructor.prototype` are **shared** across all instances, not copied
    
*   The prototype chain is a **live lookup**, not a data copy
    
*   ES6 `class` compiles to the same constructor + prototype pattern
    
*   `instanceof` walks the prototype chain — it does not check a type tag
    
*   Arrow functions cannot be constructors
    

* * *

*If this article helped you, share it with someone learning JavaScript internals. Prototype chains are one of those concepts that suddenly make everything click.*
