I am trying to distinguish certain differences in the way of creating new objects. Basically, you can create a new object via object literal ( const obj = {};
), as a member of a certain class ( const obj = new MyObjClass;
), as a result of a constructor function or by calling Object.create()
.
Every entity in javascript is an object, even functions, thus everything has .__proto__
property, but only functions may have (or may not have) .prototype
property. Child's .__proto__
property is equal to it's parent's .prototype
property. Inside .prototype
property of such functions you may find .constructor()
method, which is invoked when you are calling such functions with "new
" keyword.
This works for classes and constructor functions: you call new YourFunction()
, then in return you get a new object with it's __proto__
pointing to parent's .prototype
, also .prototype.constructor()
is invoked, which job is to set properties and methods of the final object.
But if you use Object.create()
, instead of "new
" keyword, is it possible to completely recreate the behavior of "new
" keyword?
Here I've tried to recreate it, it seems that it works fine, but when you console.dir()
every final object, you see rather different results. So..
What are the core differences between those ways of creating new objects? Is there something below the surface, or it is just the matter of personal preferences?
const objStorage = {}; // just a storage variable so it is easy to pass it to console.dir()
const obj0 = { // Declaring an object literal, so that we can pass it to Object.create()
state: "inside Object.create()",
showState() { console.log("State: " + this.state) }
}
function Obj1() { // Making constructor function
this.state = "inside constructor Function()";
this.showState = function () { console.log("State: " + this.state) }
}
class Obj2 { // Making class declaration
constructor() {
this.state = "inside Class";
this.showState = function () { console.log("State: " + this.state) }
}
}
const obj3 = function(){ // Trying to recreate class functionality, so that it can be used both ways
let self = {};
self.state = "inside self-made constructor";
self.showState = function () { console.log("State: " + this.state) }
return self
};
obj3.prototype = {};
obj3.prototype.constructor = obj3;
objStorage.a = Object.create(obj0);
objStorage.b = new Obj1;
objStorage.c = new Obj2;
objStorage.d = new obj3.prototype.constructor;
objStorage.e = Object.create(obj3());
objStorage.a.showState(); // State: inside Object.create()
objStorage.b.showState(); // State: inside constructor Function()
objStorage.c.showState(); // State: inside Class
objStorage.d.showState(); // State: inside self-made constructor
objStorage.e.showState(); // State: inside self-made constructor