There are several ways to create objects in JavaScript. The most common and recommended is the object literal, but you’ll also see new Object() and Object.create in real code. Understanding each style helps you read any JavaScript codebase.
Object Literal {} (Most Common)
The object literal is the simplest and most readable way to create objects.
// An empty object literalconst empty = {};
// An object with some basic propertiesconst point = { x: 10, y: 20,};
console.log(point.x, point.y); // 10 20You can use shorthand properties and method shorthand to remove repetition.
const name = 'Ada';const age = 36;
const user = { // Shorthand properties (name: name, age: age) name, age,
// Shorthand method syntax greet() { console.log(`Hi, I'm ${this.name} and I'm ${this.age}.`); },};
user.greet(); // "Hi, I'm Ada and I'm 36."You can also compute property names dynamically using computed property keys.
const key = 'favorite-color';const answer = 42;
const obj = { [key]: 'blue', // "favorite-color": "blue" ['answer' + answer]: 'life', // "answer42": "life"};
console.log(obj['favorite-color']); // "blue"console.log(obj.answer42); // "life"new Object() (Older but Rarely Needed)
You can create objects with the Object constructor, but the literal {} is almost always better.
// Using the Object constructorconst user = new Object();
// Add properties after creationuser.name = 'Ada';user.age = 36;
console.log(user); // { name: 'Ada', age: 36 }The literal version is shorter and clearer:
const userLiteral = { name: 'Ada', age: 36 };Object.create(proto) for Custom Prototypes
Object.create creates a new object whose prototype is the object you pass in. This is a very direct way to work with JavaScript’s prototype system.
// A prototype object with shared behaviorconst personProto = { greet() { console.log(`Hello, I'm ${this.name}.`); },};
// Create a new object that delegates to personProtoconst ada = Object.create(personProto);ada.name = 'Ada';
ada.greet(); // "Hello, I'm Ada."
console.log(Object.getPrototypeOf(ada) === personProto); // trueYou can also define properties with descriptors when creating the object.
const userWithId = Object.create(personProto, { name: { value: 'Ada', writable: true, // name can be changed enumerable: true, // shows up in Object.keys configurable: true, // descriptor can be changed/deleted }, id: { value: 123, writable: false, // read-only enumerable: false, // hidden from Object.keys configurable: false, // can’t be reconfigured },});
console.log(userWithId.name); // "Ada"console.log(userWithId.id); // 123
userWithId.name = 'Grace';console.log(userWithId.name); // "Grace"Factory Functions Returning Objects
Another common pattern is a factory function: a regular function that creates and returns an object.
// A simple factory function for usersfunction createUser(name, role = 'user') { return { name, role, describe() { console.log(`${this.name} is a ${this.role}`); }, };}
const alice = createUser('Alice', 'admin');const bob = createUser('Bob');
alice.describe(); // "Alice is a admin"bob.describe(); // "Bob is a user"Factory functions play nicely with dependency injection, testing, and functional programming, and they avoid the need for new.