Question
The new keyword in JavaScript can be confusing, especially because JavaScript is often described differently from class-based object-oriented languages.
What does the new keyword do? What problems does it solve? When is it appropriate to use it, and when should it be avoided?
Short Answer
By the end of this page, you will understand how new creates instances from constructor functions and classes, how this and prototypes are involved, and when a factory function may be a simpler alternative.
Concept
new is an operator that creates an object by calling a constructor. A constructor can be a traditional function or a JavaScript class.
function User(name) {
this.name = name;
}
const ada = new User("Ada");
In this example, new User("Ada") creates an object representing a user. The constructor initializes that object by assigning name to this.name.
When JavaScript evaluates a constructor call with new, it essentially:
- Creates a fresh object.
- Connects that object to the constructor's
prototype. - Calls the constructor with
thisset to the fresh object. - Returns the fresh object, unless the constructor explicitly returns another object.
This matters because it lets many objects share behavior efficiently through a prototype or class methods instead of copying the same methods into every object.
JavaScript supports object-oriented programming, but it uses a prototype-based object model. Classes are a cleaner syntax built on top of prototypes; they do not replace the underlying prototype system.
Mental Model
Think of a constructor as a blueprint for a type of item, such as a library-book form.
- The constructor describes how to fill in each new form.
newis the action of taking a blank form, filling it in, and handing back that particular form.- Each object has its own data, such as a different title.
- Shared methods live on the blueprint's prototype, so every book can use them without receiving a separate copy.
const firstBook = new Book("Dune");
const secondBook = new Book("Kindred");
These are two separate objects made from the same construction rules.
Syntax and Examples
Use new immediately before a constructor function or class.
const instance = new Constructor(argument1, argument2);
Constructor function
By convention, constructor function names start with a capital letter.
function Book(title, author) {
this.title = title;
this.author = author;
}
Book.prototype.describe = function () {
return `${this.title} by ${this.author}`;
};
const book = new Book("Dune", "Frank Herbert");
console.log(book.title); // Dune
console.log(book.describe()); // Dune by Frank Herbert
book gets its own title and author properties. It can also call describe() because its prototype is Book.prototype.
Class syntax
Classes provide a more structured syntax for the same common pattern.
class Book {
constructor(title, author) {
this.title = title;
this.author = author;
}
describe() {
return `${this.title} by ${this.author}`;
}
}
const book = new Book("Dune", "Frank Herbert");
console.log(book.describe());
A class constructor must be called with new. Calling Book("Dune", "Frank Herbert") throws a TypeError.
Step by Step Execution
Consider this constructor call:
function Counter(start) {
this.value = start;
}
Counter.prototype.increment = function () {
this.value += 1;
};
const counter = new Counter(5);
counter.increment();
console.log(counter.value);
Step by step:
- JavaScript sees
new Counter(5). - It creates a new empty object.
- It sets the new object's prototype to
Counter.prototype. - It calls
Counter(5)withthisreferring to that new object. - Inside
Counter,this.value = startstores5on the new object. - The constructor does not return another object, so JavaScript returns the newly created object and assigns it to
counter. counter.increment()is found onCounter.prototypeand changescounter.valuefrom5to6.- The final output is
6.
You can verify the prototype relationship:
console.log(counter instanceof Counter); // true
console.log(Object.getPrototypeOf(counter) === Counter.prototype); // true
Real World Use Cases
new is useful when an API intentionally represents reusable instances with state and shared behavior.
- Dates:
new Date()creates a date object. - Regular expressions:
new RegExp(pattern)is useful when the pattern is assembled dynamically. - Errors:
new Error("Request failed")creates an error object that can be thrown or logged. - Browser APIs:
new URL("https://example.com")parses a URL into an object with useful properties. - Application models: a
Cart,Game,WebSocketwrapper, orApiClientclass may hold state and expose related methods.
const error = new Error("Email address is required");
console.log(error.message);
const pattern = "^user-";
const userIdPattern = new RegExp(pattern);
console.log(userIdPattern.test("user-42")); // true
Real Codebase Usage
In modern application code, developers commonly use new in these situations:
Creating instances of a class
class ApiClient {
constructor(baseUrl) {
this.baseUrl = baseUrl;
}
async get(path) {
const response = await fetch(`${this.baseUrl}${path}`);
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
return response.json();
}
}
const api = new ApiClient("https://api.example.com");
The client keeps configuration (baseUrl) and groups related behavior (get).
Throwing meaningful errors
function requireName(name) {
if (!name) {
throw new Error("A name is required");
}
}
new Error() is a standard and idiomatic use of new.
Prefer factories for simple object creation
For plain data or small pieces of behavior, a factory function is often easier to read and avoids this.
function createUser(name) {
return {
name,
greet() {
return `Hello, ${name}`;
}
};
}
const user = createUser("Ada");
A useful guideline is: use new when a class or constructor represents a clear kind of instance with shared behavior or lifecycle; use object literals or factories when you only need a simple object.
Common Mistakes
Forgetting new with a constructor function
function User(name) {
this.name = name;
}
const user = User("Ada"); // Incorrect
In strict mode, this usually throws because this is undefined. In older non-strict code, it can accidentally write to the global object. Capitalize constructor names and consider using class, which throws if called without new.
const user = new User("Ada");
Using an arrow function as a constructor
const User = (name) => {
this.name = name;
};
const user = new User("Ada"); // TypeError
Arrow functions do not have their own this and cannot be used with new. Use a normal function or a class.
Defining methods inside every constructor call
function User(name) {
this.name = name;
this.greet = function () {
return `Hello, ${this.name}`;
};
}
This works, but each new User gets a separate greet function. Put shared methods on the prototype or use class methods instead.
User.prototype.greet = function () {
return `Hello, ${this.name}`;
};
Returning an object from a constructor unintentionally
function User(name) {
this.name = name;
return { name: "Replacement" };
}
const user = new User("Ada");
console.log(user.name); // Replacement
An explicitly returned object replaces the normal instance. Usually, constructors should not return objects.
Using new for plain data
const settings = new Object();
settings.theme = "dark";
Prefer an object literal when no constructor behavior is needed:
const settings = { theme: "dark" };
Comparisons
| Approach | Best for | How it creates an object | Key consideration |
|---|---|---|---|
| Object literal | Simple, known data | { name: "Ada" } | Clear and direct; no shared construction logic |
| Factory function | Simple objects, closures, flexible creation | createUser("Ada") | No new or this required |
Constructor function + new | Older codebases and prototype-based APIs | new User("Ada") | Must call it with new |
Class + new | Related state and methods with a clear instance model | new User("Ada") | Modern structured syntax; classes require new |
new versus a normal function call
function createPoint(x, y) {
return { x, y };
}
function Point(x, y) {
this.x = x;
this.y = y;
}
const a = createPoint(1, 2);
const b = new Point(1, 2);
Both create objects. The factory explicitly returns an object. The constructor relies on new to create and return the object, and can share methods through Point.prototype.
new Object() versus {}
For ordinary objects, use {}. new Object() adds no useful benefit in typical code.
new Array() versus []
For normal arrays, use []. One special case is new Array(3), which creates an array with three empty slots, not [3]; this can be surprising.
Cheat Sheet
// Constructor function
function User(name) {
this.name = name;
}
const user = new User("Ada");
// Class
class User {
constructor(name) {
this.name = name;
}
}
const user = new User("Ada");
new Constructor(args)creates an instance.- It sets the instance prototype to
Constructor.prototype. - Inside a normal constructor,
thisrefers to the new instance. - Constructors conventionally use
PascalCase:User,Cart,ApiClient. - Put shared constructor-function methods on
.prototype. - Class methods are shared through the class prototype automatically.
- Classes must be called with
new. - Arrow functions cannot be called with
new. - A constructor that returns an object replaces the normally created instance.
- Prefer
{}for plain objects and[]for normal arrays. - Common built-in uses:
new Date(),new Error(message),new URL(value), andnew RegExp(pattern).
FAQ
Is JavaScript object-oriented if it uses new?
Yes. JavaScript supports object-oriented programming, primarily through objects and prototypes. Its class syntax provides a familiar way to work with prototype-based behavior.
What exactly does new return in JavaScript?
It normally returns the new object created for the constructor call. If the constructor explicitly returns another object, that returned object is used instead.
Do I always need new to create an object?
No. Object literals, arrays, factory functions, and functions that return objects can all create objects without new.
Should I use classes or constructor functions?
For new code that needs instance-based behavior, classes are usually easier to read. Constructor functions remain important when working with older code and understanding prototypes.
Why do constructor names start with a capital letter?
It is a convention that signals the function is intended to be called with new. It helps prevent accidental normal function calls.
Can an arrow function be used with new?
No. Arrow functions are not constructible and throw a TypeError when used with new.
What is the difference between new Error() and throw new Error()?
new Error() creates an error object. throw new Error() creates it and immediately transfers control to error-handling code.
Is instanceof always the best way to identify objects?
Not always. It checks a prototype relationship and can be unreliable across separate JavaScript realms, such as different browser frames. Often, checking needed properties or using explicit application data is more practical.
Mini Project
Description
Build a small Task class for a command-line-style task list. The project demonstrates how new creates independent task instances while class methods provide shared behavior for every task.
Goal
Create task objects with a title and completion state, then mark and display each task.
Requirements
Create a Task class that accepts a task title.
Create each task with new.
Give every new task an incomplete status by default.
Add a method that marks a task as complete.
Add a method that returns a readable task description.
Create and display at least two separate tasks.
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.