JavaScript's Object Creation Fundamentals
JavaScript's Object Creation Fundamentals
In JavaScript, every object is instantiated through a function constructor, even when using literal syntax.
Function Constructors and Object Creation
Consider the following example of creating an object using a function constructor:
function Person(name, birthYear) {
this.name = name;
this.birthYear = birthYear;
}
const person1 = new Person('Alex Johnson', 1990);
The person1 object is created using the Person function constructor. But what about objects created using literal notation?
Literal Syntax as Syntactic Sugar
When we use object literal syntax, it's actually a convenient shorthand provided by the language:
const sampleObj = { x: 15, y: 30 };
const sampleArray = [3, 'y', false];
These literal notations are syntactic sugar. Their underlying implementation is equivalent to:
// Object literal implementation
const obj = new Object();
obj.x = 15;
obj.y = 30;
// Array literal implementation
const arr = new Array();
arr[0] = 3;
arr[1] = 'y';
arr[2] = false;
The Object and Array mentioned above are actually function constructors:
console.log(typeof Object); // function
console.log(typeof Array); // function
This confirms that all JavaScript objects are created through function constructors.
The Prototype Chain
Every JavaScript object has a __proto__ property that references the prototype of its constructor function.
const emptyObj = {};
console.log(emptyObj.__proto__ === Object.prototype); // true
The emptyObj object is created by the Object function, so its __proto__ property points to Object.prototype.
Interestingly, Object.prototype itself is an object, and its __proto__ property points to null:
console.log(Object.prototype.__proto__); // null
Functions as Objects
Functions in JavaScript are also objects. They have a __proto__ property and are created by the Function constructor:
// Traditional function declaration
function greet() {
return 'Hello';
}
// Function constructor approach (not recommended)
const greet2 = new Function('return "Hello"');
The second approach demonstrates that functions are created by the Function constructor, though it's not recommended for practical use.
The Function Constructor Relationship
Based on our understanding that an object's __proto__ points to its constructor's prototype, we can observe:
console.log(Object.__proto__ === Function.prototype); // true
console.log(Array.__proto__ === Function.prototype); // true
console.log(Function.__proto__ === Function.prototype); // true
The last equality creates a circular reference. This is because Function is itself a function and is created by the Function constructor, resulting in Function.__proto__ pointing to Function.prototype.
This creates a circular but consistent structure in JavaScript's prototype chain.