JavaScript Object Constructors
Object constructors are functions used to create multiple objects with the same structure and behavior. They serve as blueprints for objects. JavaScript provides constructor functions, the new keyword, prototypes, instanceof, Object.create(), and the modern class syntax.
Constructor Functions
A constructor function is a regular function that is designed to be called with the 'new' keyword. By convention, constructor names start with a capital letter. Inside the constructor, 'this' refers to the new object being created.
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function() {
return `Hi, I'm ${this.name}, ${this.age} years old`;
};
}
let alice = new Person("Alice", 30);
let bob = new Person("Bob", 25);
console.log(alice.greet());
console.log(bob.greet());
console.log(typeof alice);
console.log(alice.constructor === Person);The new Keyword
The 'new' keyword does four things: (1) creates a new empty object, (2) sets the prototype of the new object to the constructor's prototype, (3) binds 'this' to the new object and runs the constructor, (4) returns the new object (unless the constructor returns a different object).
function Car(brand, model) {
// 'new' creates {} and sets this = {}
this.brand = brand;
this.model = model;
// 'new' implicitly returns this
}
let car1 = new Car("Toyota", "Camry");
let car2 = new Car("Honda", "Civic");
console.log(car1);
console.log(car2);
// Without 'new', it's just a regular call (BAD!)
// let car3 = Car("Ford", "Focus");
// console.log(car3); // undefined! 'this' was global
// Simulating what 'new' does internally
function simulateNew(Constructor, ...args) {
let obj = Object.create(Constructor.prototype);
let result = Constructor.apply(obj, args);
return result instanceof Object ? result : obj;
}
let car3 = simulateNew(Car, "Ford", "Focus");
console.log(car3);Prototype Chain Basics
Every function has a prototype property. When you create an object with 'new', the object's internal prototype links to the constructor's prototype. This allows shared methods to live on the prototype instead of being duplicated on every instance.
function Animal(name, sound) {
this.name = name;
this.sound = sound;
}
// Shared method on the prototype
Animal.prototype.speak = function() {
return `${this.name} says ${this.sound}!`;
};
Animal.prototype.type = "Animal";
let dog = new Animal("Rex", "Woof");
let cat = new Animal("Whiskers", "Meow");
console.log(dog.speak());
console.log(cat.speak());
// Method is shared, not duplicated
console.log(dog.speak === cat.speak);
// Instance property vs prototype property
console.log(dog.hasOwnProperty("name"));
console.log(dog.hasOwnProperty("speak"));instanceof and Object.create()
The instanceof operator checks if an object was created by a specific constructor (or has it in its prototype chain). Object.create() creates a new object with a specified prototype, allowing prototypal inheritance without constructors.
function Shape(type) {
this.type = type;
}
let circle = new Shape("circle");
console.log(circle instanceof Shape);
console.log(circle instanceof Object);
console.log("hello" instanceof Shape);
// Object.create() — create with specific prototype
let personProto = {
greet() {
return `Hi, I'm ${this.name}`;
}
};
let alice = Object.create(personProto);
alice.name = "Alice";
alice.age = 30;
console.log(alice.greet());
console.log(Object.getPrototypeOf(alice) === personProto);
// Object with no prototype
let bare = Object.create(null);
bare.x = 1;
console.log(bare.x);
// bare has no toString, valueOf, etc.Class Syntax Preview
ES6 classes provide a cleaner syntax for constructor functions and prototypes. Under the hood, classes are still functions and prototypes — they are 'syntactic sugar'. Classes make constructor patterns more readable and familiar.
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hi, I'm ${this.name}`;
}
getAge() {
return this.age;
}
}
let alice = new Person("Alice", 30);
let bob = new Person("Bob", 25);
console.log(alice.greet());
console.log(bob.getAge());
console.log(alice instanceof Person);
// Classes are functions under the hood
console.log(typeof Person);
console.log(alice.greet === bob.greet);| Approach | Syntax | Best For |
|---|---|---|
| Constructor function | function Foo() { this.x = 1 } | Traditional pattern |
| Prototype methods | Foo.prototype.bar = fn | Shared methods |
| new keyword | new Foo() | Creating instances |
| instanceof | obj instanceof Foo | Type checking |
| Object.create(proto) | Object.create(parent) | Prototypal inheritance |
| class | class Foo { constructor() {} } | Modern, clean syntax |