cf.completefrontendCode editorOpen lab
THE JAVASCRIPT FIELD GUIDE

Constructors & new

Create many similar JavaScript objects from one function, understand what new does, guard constructors with new.target, and predict constructor return values.

By the end, you can
  • 01
    Build similar objectsWrite a capitalized constructor function that assigns properties to this.
  • 02
    Trace newExplain the fresh object, prototype link, this binding, and return rule.
  • 03
    Handle edge casesUse new.target, predict constructor returns, and avoid wrapper-object traps.

One recipe, many objects

An object literal is perfect when you need one object: { name: "Ada" }. But apps often need many objects with the same shape: many users, many books, many tasks, many cart items. A constructor function is an older JavaScript pattern for making those similar objects from one reusable function.

You call a constructor with the new operator. The constructor receives a fresh object as this, writes properties onto it, and gives that object back. If you already know functions, Declaring & calling functions, and methods where this is the object before the dot, this lesson connects those ideas to object creation.

Real-life analogyCookie cutter plus fresh dough

A constructor is a cookie cutter. new is the press into fresh dough. Every press makes a new cookie with the same shape, but each cookie can have its own sprinkles: ada.name is separate from grace.name.

In real life: The cookie cutter
In JavaScript: The constructor function, such as User
In real life: Pressing the cutter into dough
In JavaScript: Calling it with new User(...)
In real life: Each cookie
In JavaScript: Each separate object returned by new
In real life: Sprinkles on one cookie
In JavaScript: Own properties like name and role

Where the analogy stops: A cookie cutter stamps physical dough. A constructor runs code, so it can validate inputs, choose defaults, and even return a different object.

Classes are the modern surface

Modern JavaScript usually writes this pattern with classes. Classes are built on the same idea: a constructor call creates an object and links it to shared behavior. Stage 5 has separate lessons for The prototype chain, F.prototype & constructors, and Class basics; this lesson gives you the foundation.

Constructor functions

FOUNDATION

A constructor function is just a regular function that is meant to be called with new. By convention its name starts with a capital letter: User, Book, Task. The capital is not required by the language, but it tells humans, “use new here.”

Two users from one constructorPop out in the code editor (opens in a new tab)JavaScript
function User(name) {
  this.name = name;
  this.role = "learner";
}

const ada = new User("Ada");
const grace = new User("Grace");
console.log(ada.name, grace.name);
console.log(ada === grace);

Line 1 defines the constructor. Lines 2 and 3 write properties on this. When line 6 runs, new supplies a fresh object as this, so ada gets its own name and role. Line 7 presses the same cookie cutter again, making a different object for Grace.

  • ada.name is "Ada"; grace.name is "Grace".
  • ada === grace is false because each new call returns a separate object.
  • Arrow functions cannot be used with new, because arrows do not have constructor behavior or their own this.
Forgetting new

In strict code, calling User("Ada") without new makes this be undefined, so this.name = name throws a TypeError. In sloppy classic scripts, the same mistake can write a global property instead. The tests for this lesson prove both behaviors with real JavaScript.

What new does

STEP THROUGH

The new operator is a small routine with four important steps:

  1. Create a fresh empty object.
  2. Link that object to Constructor.prototype.
  3. Call the constructor with this set to the fresh object.
  4. Return the fresh object, unless the constructor returns its own object.
Real-life analogyThe bakery routine

Think of new as a bakery routine. Before your constructor decorates anything, the bakery has already grabbed a fresh tray and stamped it with the shop’s logo. Then your function adds the details and hands the pastry over.

In real life: Grab a fresh tray
In JavaScript: Create a new empty object
In real life: Stamp the shop logo on it
In JavaScript: Link it to Constructor.prototype
In real life: Decorate the pastry
In JavaScript: Run the constructor with this set to the object
In real life: Hand it to the customer
In JavaScript: Return the constructed object

Where the analogy stops: Real bakeries do not have prototype chains. The logo stamp is only a memory aid for JavaScript’s shared-method lookup.

The replay below uses a real hand-written helper named createWith. It is a teaching model, not a replacement for new. The tests prove that this helper and real new User("Ada") produce equivalent objects: same own property, same prototype, and instanceof is true.

Model the four steps of new
Step 0 of 7Ready
Your turn: follow the blue line

This helper is a teaching model of new: create, link, call, return. Step through it beside the real new User("Ada") result.

Running in
  1. script
Next: line 2
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
function createWith(Constructor, ...args) {  const result = Constructor.apply(obj, args);  return result !== null && (typeof result === "object" || typeof result === "function")    ? result    : obj;} function User(name) {  this.name = name;} const real = new User("Ada");const model = createWith(User, "Ada");console.log(real.name === model.name);console.log(Object.getPrototypeOf(real) === Object.getPrototypeOf(model));console.log(model instanceof User);
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

new.target

INTERACTIVE

Inside a normal function, new.target tells you how the function was started. If the call used new, it is the constructor function. If the call did not use new, it is undefined.

That gives constructors a way to fail clearly or auto-correct. This version auto-corrects: if (!new.target) return new SafeUser(name). Some codebases prefer throwing a TypeError so bugs are noticed immediately.

Watch new.target change
Step 0 of 6Ready
Your turn: follow the blue line

Switch the setting to see how new.target changes. It is undefined for a normal call and the constructor function for a new call.

Running in
  1. script
Next: line 8
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
function SafeUser(name) {  if (!new.target) {    return new SafeUser(name);  }  this.name = name;} console.log(ada.name);
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
Choose the call on line 8

Changing the call starts a fresh replay. Predict whether line 2 runs the guard.

A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

Returning from constructors

EDGE CASES

Most constructors do not write return. They assign to this, and new returns that object. But JavaScript has one unusual rule: returning an object replaces the fresh object, while returning a primitive is ignored.

Object returns replace; primitive returns are ignoredPop out in the code editor (opens in a new tab)JavaScript
function ReturnsObject() {
  this.name = "built";
  return { name: "replacement" };
}

function ReturnsPrimitive() {
  this.name = "built";
  return "ignored";
}

console.log(new ReturnsObject().name);
console.log(new ReturnsPrimitive().name);
Constructor return rules
Constructor bodyWhat new returnsWhy
No explicit returnthe new objectnew User("Ada") returns the object that this received
Return a primitivethe new objectreturn "ignored" is ignored by new
Return an objectthat returned objectreturn { name: "replacement" } replaces the fresh object
Return a functionthat function objectFunctions are objects, so they replace the fresh object too

This is rare in everyday constructors, but it explains weird library code and some interview puzzles. If you see a constructor returning an object, read that line as “replace the cookie.” If it returns a number, string, boolean, null, or undefined, new keeps the object it already made.

Shared methods and the prototype link

COMPARE

If you put a function inside a constructor, every instance gets its own copy of that function. That works, but it wastes memory and makes comparisons surprising. Put the method on Constructor.prototype instead, and all instances share the same function.

Copied method vs shared methodPop out in the code editor (opens in a new tab)JavaScript
function CopiedMethodUser(name) {
  this.name = name;
  this.greet = function () {
    return "Hi, " + this.name;
  };
}

function SharedMethodUser(name) {
  this.name = name;
}
SharedMethodUser.prototype.greet = function () {
  return "Hi, " + this.name;
};

const copiedA = new CopiedMethodUser("Ada");
const copiedB = new CopiedMethodUser("Grace");
const sharedA = new SharedMethodUser("Ada");
const sharedB = new SharedMethodUser("Grace");
console.log(copiedA.greet === copiedB.greet);
console.log(sharedA.greet === sharedB.greet);
console.log(sharedA.greet());

The second pattern works because new links the created object to SharedMethodUser.prototype. When sharedA.greet() is called, JavaScript does not find greet as an own property, so it looks along that link and finds the shared method. The prototype lessons later make that lookup precise.

Where should the method live?
PatternComparisonUse it when
this.greet = function () { ... } inside the constructora.greet !== b.greetThe function truly needs per-instance private data from its creation
User.prototype.greet = function () { ... }a.greet === b.greetMost constructor methods; one shared function can use this for each instance
class User { greet() { ... } }Methods also live on the prototypeModern code; Class basics covers the syntax later

Built-in constructors and wrapper traps

SORT

JavaScript has built-in constructors too. new Date() creates a Date object. new Map() creates a keyed collection you will study in a later lesson. But new Number(5), new String("x"), and new Boolean(false) create wrapper objects, and those are usually a trap.

Wrapper objects are objectsPop out in the code editor (opens in a new tab)JavaScript
console.log(typeof new String("x"));
console.log(Boolean(new Boolean(false)));
console.log(typeof "x");
console.log(Boolean(false));

The dangerous one is new Boolean(false). The value inside it represents false, but the wrapper itself is an object, and all objects are truthy. Prefer primitives: 5, "x", and false, or use Number(value), String(value), and Boolean(value) as plain conversion functions.

Needs new, plain call, or avoid new?
  • Date object for a timestamp: new Date()
  • Map collection: new Map()
  • Your User constructor
  • Number parsing: Number("5")
  • Make an array from an iterable: Array.from(items)
  • Text value: new String("x")
  • Boolean value: new Boolean(false)
  • One small record: { name: "Ada" }
Try it yourself
0 of 8 correct

Sort each case by how you should call it in everyday JavaScript. The explanations point out the traps.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Where you’ll use this

You will meet constructor behavior in three places. First, older code and some libraries still expose constructor functions. Second, built-in data structures such as Date, Map, Set, URL, and many browser objects are constructed with new. Third, classes use the same construction pathway with a cleaner syntax.

A small practical constructorPop out in the code editor (opens in a new tab)JavaScript
function CartItem(name, price, quantity) {
  if (!new.target) return new CartItem(name, price, quantity);
  this.name = name;
  this.price = price;
  this.quantity = quantity;
}

CartItem.prototype.total = function () {
  return this.price * this.quantity;
};

const apples = new CartItem("Apples", 2, 3);
console.log(apples.total());

This is not the only way to model data. Object literals, factory functions, and classes are all useful. Constructors are worth learning because they explain the common new Something() shape and prepare you for prototypes and classes.

Common misconceptions

“A constructor is a special kind of declaration.”

It is usually an ordinary function used with new. The call site changes what happens.

“The capital letter makes new work.”

The capital letter is only a convention for humans. JavaScript does not enforce it.

“new copies prototype methods into every object.”

No copy happens. new creates a link to Constructor.prototype, and property lookup can follow that link.

“Returning anything from a constructor replaces the instance.”

Only object and function returns replace it. Primitive returns are ignored.

“new Boolean(false) behaves like false.”

It is an object, so it is truthy. Avoid wrapper constructors for primitives.

Misconception shortcut

If a constructor puzzle confuses you, ask two questions: did the call use new, and did the constructor return an object? Those two answers predict most of the result.

Practice: constructors and new

5 EXERCISES
Exercise 1 · Warm-upWrite a Book constructor

Create a Book constructor with title and author, then construct one book and print it.

Starter codePop out in the code editor (opens in a new tab)JavaScript
function Book(title, author) {
  this.title = title;
  this.author = author;
}

const dune = new Book("Dune", "Frank Herbert");
console.log(dune.title + " by " + dune.author);

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · PracticePredict separate instances

    Predict the two output lines. This checks both identity with === and membership with instanceof.

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    function Pet(name) {
      this.name = name;
    }
    
    const a = new Pet("Mochi");
    const b = new Pet("Mochi");
    console.log(a === b);
    console.log(a instanceof Pet);

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeFix a missing new bug

      A teammate wrote Task("Ship lesson") without new. Add a guard that auto-corrects the call.

      Starter codePop out in the code editor (opens in a new tab)JavaScript
      function Task(title) {
        if (!new.target) return new Task(title);
        this.title = title;
      }
      
      const task = Task("Ship lesson");
      console.log(task.title);

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeEnforce new with an error

        Write an Account constructor that throws a helpful TypeError when someone forgets new.

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        function Account(name) {
          if (!new.target) {
            throw new TypeError("Use new with Account");
          }
          this.name = name;
        }
        
        console.log(new Account("Ada").name);

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengePredict a replacement return

          Predict what the constructor returns when it assigns one object but returns another.

          Starter codePop out in the code editor (opens in a new tab)JavaScript
          function Ticket() {
            this.code = "A1";
            return { code: "VIP" };
          }
          
          console.log(new Ticket().code);

          Answer, then press Check. Spacing and letter case don’t matter.

            Quiz: check your understanding

            7 QUESTIONS

            Read each snippet carefully. Your first try counts, but every option explains why it is right or wrong.

            Lesson quiz · 7 questionsScore: first tries count
            1. Question 1 of 7What is the usual naming convention for constructor functions?

              Choose an answer to see the explanation.

            2. Question 2 of 7What does the User constructor print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              function User(name) {
                this.name = name;
              }
              const ada = new User("Ada");
              console.log(ada.name);

              Choose an answer to see the explanation.

            3. Question 3 of 7Which step is not part of what new User("Ada") does?

              Choose an answer to see the explanation.

            4. Question 4 of 7What does a primitive-returning constructor print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              function Box() {
                this.label = "fresh";
                return "ignored";
              }
              console.log(new Box().label);

              Choose an answer to see the explanation.

            5. Question 5 of 7What does an object-returning constructor print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              function Box() {
                this.label = "fresh";
                return { label: "replacement" };
              }
              console.log(new Box().label);

              Choose an answer to see the explanation.

            6. Question 6 of 7Inside a normal function, what is new.target when the function was called without new?

              Choose an answer to see the explanation.

            7. Question 7 of 7What do wrapper constructors print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              console.log(typeof new String("x"));
              console.log(Boolean(new Boolean(false)));

              Choose an answer to see the explanation.

            Key takeaways

            • Constructor functions are regular functions intended to be called with new; capitalize their names by convention.
            • new creates a fresh object, links it to Constructor.prototype, calls the function with this set to that object, and returns it.
            • new.target is undefined for plain calls and the constructor for new calls, so it can guard mistakes.
            • Returning an object from a constructor replaces the fresh object; returning a primitive is ignored.
            • Put shared methods on the prototype or use class syntax later; avoid primitive wrapper constructors.

            Remember the one-liner.
            A constructor plus new is a reusable recipe for making separate objects with the same shape.

            Up next: Object.keys, values & entries.

            CompleteFrontend Clear concepts. Working examples.