1

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");
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
David542
  • 104,438
  • 178
  • 489
  • 842
  • 1
    In the first example the invocation of `basicConstructor.call` is not needed, for everything needed already gets done by `Object.create(basicPrototype.prototype)` all alone, just try it ... `let basicObj = Object.create(basicPrototype.prototype); basicObj.sayHi("Tommy");` ... already is perfectly fine. Doing it with `basicConstructor.call` is just like passing `basicObj` to it ... `basicConstructor.call(basicObj)` ... and nothing happens since the delegated `basicObj` gets not mutated, just returned by what the OP calls `basicConstructor`. The latter and calling it it just totally unnecessary. – Peter Seliger Apr 07 '22 at 20:14
  • 1
    The same applies to the second example code ... `let basicObj = Object.create(basicPrototype);` ... is everything needed. Thus, the real question is ... _"What is the difference in between the object creation of `Object.create(basicPrototype.prototype)` and. `Object.create(basicPrototype)`?"_ – Peter Seliger Apr 07 '22 at 20:24
  • @PeterSeliger I see, thanks for clarifying. Would you want to write an answer combining your two comments plus the `.prototype` thing? – David542 Apr 07 '22 at 20:25
  • 1
    Answer hereby provided. – Peter Seliger Apr 07 '22 at 21:00
  • I had to rework/correct/improve my answer since I overlooked a minor but important implementation detail of your second example's code. In an interview question I would have failed. – Peter Seliger Apr 07 '22 at 21:36
  • 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. – Peter Seliger Apr 08 '22 at 12:25

1 Answers1

1

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.

Peter Seliger
  • 11,747
  • 3
  • 28
  • 37