In the absence of using the class
keyword, what is the difference between the following two ways to construct an inherited object? In the first one I'm attaching things on the .prototype
and in the second one I'm doing it directly on the function. What would be the difference?
function basicPrototype(){};
basicPrototype.prototype.sayHi = function(name){
console.log("Hello,", name);
}
function basicConstructor() {
return this; // make sure to pass it a this
}
let basicObj = basicConstructor.call(Object.create(basicPrototype.prototype));
basicObj.sayHi("Tommy");
And removing the .prototype
on the two lines?
function basicPrototype(){};
basicPrototype.sayHi = function(name){
console.log("Hello,", name);
}
function basicConstructor() {
return this; // make sure to pass it a this
}
let basicObj = basicConstructor.call(Object.create(basicPrototype));
basicObj.sayHi("Tommy");
The code of both examples can be cleaned up since basicConstructor.call
does not have any effect to the passed object which shortly before was created via Object.reate
.
In addition basicConstructor
despite its name is not a constructor at all since it never creates instances due to never being invoked with new
. (It also does not feature any implementations neither within the function body nor own prototypal ones.) Thus basicConstructor
acts more like a (identity?) function/method which returns the reference of its call time's this
context. So it's dispensable.
From the above comments ...
Thus, the real question is ... "What is the difference in between the object creation of
Object.create(basicPrototype.prototype)
andObject.create(basicPrototype)
?"
Well it is pretty obvious that the former creates a new object with basicPrototype.prototype
set as the new object's prototype, the latter creates an object which has the function basicPrototype
set as the new object's prototype ...
... which means that calling/sending sayHi
on/to basicObj
for both cases technically is the same. Since basicObj
has not such an own property there will be lookups into both object's prototype chains.
And both methods are found immediately since both prototypes feature sayHi
as their own property which is clear for the former case but (for some) maybe surprising for the latter case. (I had to look at it twice/three times myself and countercheck again.) The second example does implement and assign sayHi
as direct property to the function basicPrototype
. Thus for the latter case the function mainly acts as a dump object like basicPrototype.prototype
does for the former case.
As final conclusion one could state. The example code is a tricky brainteaser where at no point anything class related (in terms of constructor functions and constructor function prototypes) is involved. Everything gets achieved by the class/constructor less alternative of Object.create
. The rest is just tricky, harmless obfuscation.