import {NOTE} from './_util'

How the new keyword works

This module will implement the JavaScript's new keyword as a function, that can be invoked on a normal constructor function to faithfully replicate the keyword's functionality. The function is by no means useful in real-life situations. It's purpose is to reveal the guts of the new keyword so you can understand what it does.

For more information on prototypal inheritance in JavaScript (which covers the usage of constructor functions), take a look at the proto module.

We will start by defining a constructor function.

function Foo(name) {
  this.name = name
}

We also want the objects to inherit some properties, which we will set using the constructor's prototype property.

Foo.prototype.exclaim = function () {
  console.log(this.name + '!')
}

Normally, we would use this constructor like so:

NOTE('Create foo using Foo constructor')
let foo = new Foo('Superman')
console.log('foo.name ===', foo.name) // foo.name === Superman

NOTE('foo.exclaim()')
foo.exclaim() // Superman!

A function that replaces the new keyword may look something like this:

const neo = function (ctor, ...ctorArgs) {
  // Create the new object
  let obj = {}
  // Set the object's prototype to constructor's `prototype` property
  Object.setPrototypeOf(obj, ctor.prototype)
  // Apply the constructor to the new object using constructor arguments
  ctor.apply(obj, ctorArgs)
  // Return the new object
  return obj
}

Let's see if the function actually does what we want.

NOTE('Create bar using Foo constructor and neo() function')
let bar = neo(Foo, 'Batman')
console.log('bar.name === ', bar.name) // bar.name === Batman

NOTE('bar.exclaim()')
bar.exclaim() // Batman!

Hopefully, the new keyword has been demystified and you have a better understanding of what exactly it does.

NOTE: In the example function, the first and second step can be merged into a single Object.create() call. This has not been done in order to break down the operations that the new keyword performs. A slightly shorter version of the neo() function may look like this:

const neo2 = function (ctor, ...ctorArgs) {
  let obj = Object.create(ctor.prototype)
  ctor.apply(obj, ctorArgs)
  return obj
}

results matching ""

    No results matching ""