DEV Community

What is Javascript's `new` keyword doing under the hood?

Vince Campanale on June 20, 2017

Good morning, afternoon, evening, night. I have some things to share with you about the new keyword in Javascript. Important things. I'll start w...
Collapse
 
qwemaze profile image
Elias Baryshnikov

In the edge case you should return this

Collapse
 
vincecampanale profile image
Vince Campanale

Okay, changed it. Is it correct now?

Collapse
 
qwemaze profile image
Elias Baryshnikov • Edited

Well, now I think you do not completely understand it yourself.

In the new2 function you apply the constructor to newObject, which makes 'this' inside the constructor to reference newObject, therefore after modifying 'this' in the constructor it should return 'this'.
After that new2 can just return the result of 'constructor.apply' which is the reference to newObject.

P.S. Cannot really edit with markdown from a mobile.

Thread Thread
 
vincecampanale profile image
Vince Campanale • Edited

You are correct -- I'm certainly having difficulty with understanding how to handle the edge case(s). Always learning! Thanks for taking the time to discuss it with me.

So, it sounds like my initial implementation of new2 was correct to return constructor.apply(newObject, constructorArgs) || newObject, but you are saying the Constructor function itself (in the edge case) should return this rather than the object it is currently returning? I believe that would actually be a new edge case (in addition to the one presented above).

I tested my implementation in a REPL and it is handling the edge case of a Constructor returning an object correctly.

Would you mind providing a code snippet or copying and correcting the code in the article to convey your insight?

Thanks again for contributing!

Thread Thread
 
qwemaze profile image
Elias Baryshnikov • Edited

If constructor returns

    return {
      doors,
      color
    }
Enter fullscreen mode Exit fullscreen mode

it is a completely different from newObject object reference and after that if new2 returns the result of constructor the newObject would be just lost in the new2 scope.

So it have to be like

function Car(doors, color) {
    this.doors = doors;
    this.color = color;
    this.drive = () => console.log('Vroom!');
    return this // equals to `newObject` ref
}

function new2(constructor, ...constructorArgs) {
    const newObject = {};
    Object.setPrototypeOf(newObject, constructor.prototype);
    return constructor.apply(newObject, constructorArgs); // bind newObject to constructor's `this` reference and call with args
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
vincecampanale profile image
Vince Campanale

Ah okay, I see what you're saying now. I guess part of what I was trying to convey is that the constructor function can in fact return any object. In which case, the new function should just return that object as is.

What you've presented here is a more realistic edge case. I will think about a way to cover it in the article.

Great insights -- thank you.

Collapse
 
vincecampanale profile image
Vince Campanale

Nice catch Elias -- thank you for bringing it up. I'll fix it tonight!

Collapse
 
antonfrattaroli profile image
Anton Frattaroli

Fantastic article. I was just wondering about this today.

Collapse
 
binaryforgeltd profile image
Bart Karalus

Nice article overall but the most interesting bit..."give a couple arguments for avoiding this approach(...)"

... has never happened! :-)

Collapse
 
vincecampanale profile image
Vince Campanale

You're right! The article ended up getting quite long, so I decided to leave that part for a follow-up. I guess it's a cliffhanger for now ;)

Collapse
 
vinh profile image
Vinh

Great article. I put this link in our news letter so other can find it as well: betterdev.link/issues/6