loading...
Cover image for The new keyword

The new keyword

shaneallantaylor profile image Shane Taylor (he/him) Updated on ・2 min read

Let's make use of some syntactical sugar - new.

The new keyword does a bunch of neat shit for us, but to fully appreciate what it does, we've gotta review something else real quick:

Functions in JavaScript are both objects and functions.

This means that this code actually works:

function sayHey() {
  console.log('Heeeeey');
}

sayHey.target = 'Tang';
console.log(sayHey.target); // will log 'Tang' to the console

Cool!

So functions are both objects and functions - we can access the function bit with parentheses (sayHey()) and we can access the object bit with dot notation (sayHey.something).

The object portion of functions is always there and it always has a prototype key in it. And the value stored at the prototype key? It's a big ol' empty object and it's exactly where we want to store our functions.

Now we need to talk about the cool shit new does for us in JavaScript. The new keyword modifies the execution context of the function that immediately follows it by doing the following:

  • It creates a property labeled this and assigns an empty object to that label
  • On the this object from above, the hidden property __proto__ is assigned the reference to the prototype property on the function being invoked
  • It returns the object stored at the this property as long as no object is returned from the function being invoked (h/t to Thomas Broyer for clarifying this point)

We would have to do all that stuff manually, but the new keyword does all of that for us.

Finally, let's take a look at it in action:

function createCar(color, speed) {
  this.color = color;
  this.speed = speed;
}

createCar.prototype.go = function () {
  console.log('I prefer to drive ' + this.speed + '.');
}

const myCar = new createCar('red', 'fast');
myCar.go(); // will log 'I prefer to drive fast.' to the console
console.log('myCar is', myCar.color); // will log 'myCar is red' to the console

Posted on May 19 '19 by:

shaneallantaylor profile

Shane Taylor (he/him)

@shaneallantaylor

Front-end focused, forever in pursuit CSS solutions and finding balance. I dig the React community and find kinship with lifelong learners. New 'favorite emoji' every other week. Current fave: πŸ„

Discussion

markdown guide
 

Correct me if I'm wrong, but if the function returns a value, the new invocation will actually return that value rather than the this. I have no idea why it works that way though, as it's really unintuitive, but I think one had to decide what to do in such case and ignoring the return value would have been weird too (throwing an error? Well, why not…)

 

Hey Thomas!

From my testing, it looks like new will still return the object stored at the this property from the function being altered by new.

For example:

function createCar(color, speed) {
  this.color = color;
  this.speed = speed;
  return 'Cars are cool!';
}

createCar.prototype.go = function () {
  console.log('I prefer to drive ' + this.speed + '.');
}

const myCar = new createCar('red', 'fast');
myCar.go();
console.log('myCar is', myCar);

const newCar = new createCar('green', 'slow');
console.log('newCar is', newCar);

Both of the console logs above return the object stored at this during the execution of createCar.

Good question though! Let me know if you see any issues with my logic - would love to know more!

 

It's because you return a string. If you returned an object, it would be used instead.

See also developer.mozilla.org/en-US/docs/W...

Thomas, you are sooooo right.

function createCar(color, speed) {
  this.color = color;
  this.speed = speed;
  return { motto: 'Cars are cool' };
}

createCar.prototype.go = function () {
  console.log('I prefer to drive ' + this.speed + '.');
}

const myCar = new createCar('red', 'fast');
console.log('myCar is', myCar); // will log the object with the 'motto' key :( :(

Thank you for highlighting this oddity. I'll be updating the article and including this in an upcoming post about things to be cautious of with the new keyword.