Defining a class with or without the .prototype

108 views Asked by At

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");

1

There are 1 answers

0
Peter Seliger On BEST ANSWER

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) and Object.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.