New things about new operator in JavaScript.

Hello Devs, hope you all are doing great, now as i have got your attention, not taking much of your time, lets jump on today's topic, its the operator NEW, we all know what is does with classes, and constructor functions, it basically returns an instance of any Object. According to MDN

The new operator lets developers create an instance of a user-defined object type or of one of the built-in object types that has a constructor function.

But today we'll learn how it does that, so without wasting any further time, lets dive deeper, we'll be studying this in 2 step approach

  1. I will explain exactly what the new keyword is doing under the hood.
  2. Next, I will show how it does what it does by implementing it in code.

step 1, what it does

  1. it creates a new object (empty object).
  2. takes the prototype of function/object that is passed and sets/appends the prototype to newly created empty object.
  3. in the case of (constructor function) it calls the function with newly created object (empty object) using apply() (func.apply(obj, argsArr)).
  4. lastly returns the newly created Object.

as the above steps are self explanatory, still we'll discuss them, starting from the first step that is, as we call new operator, what it is internally does is it firstly creates an empty with no-prototype (it is just an empty object), then it takes the prototype of the function which it is called with and applies to the empty object, then it calls the same function as a method of newly created object by the help of Function.bind and lastly it returns the newly created object.

Now lets take a look at practical example

function Temp() {
  this.dummyValue = "dummyValue";
}
Temp.prototype.dummyMethod = function () {
  console.log("this is dummy method");
};

function getNewObj(func) {
  const newObject = {};
  Object.setPrototypeOf(newObject, func.prototype); // setting the prototype of function to the object, and as everything in javascript is a Object functions also have prototype property 
  func.apply(newObject); // here we are calling the function (Temp in this case) on newObject
  return newObject;
}

var myObj = getNewObj(Temp); // passing this constructor function as param
console.log(myObj);  // Temp {dummyValue: "dummyValue", dummyMethod: ƒ (),constructor: Object}
myObj.dummyMethod(); // this is dummy method

hmm, you might that what if a function returns something like a primitive value or an Object, lets cover that case as well

function returnObject() {
  const object = {
    name: "Raunak",
    lastName: "to_be kept_secret",
    method: function () {
      return `${this.name} ${this.lastName}`;
    }
  };
  return {
    ...object,
    returnFromFunction: true
  };
}

function getNewObj2(func) {
  const newObject = {};
  Object.setPrototypeOf(newObject, func.prototype);
  const returnResults = func.apply(newObject);
  if (typeof returnResults === "object") {
    return returnResults;
  }
  return newObject;
}

var myObj2 = getNewObj2(returnObject);
console.log({ myObj2, functionResult: myObj2.method() });
// OP {myObj2: Object, functionResult: "Raunak to_be kept_secret"}

in this post i have used function keyword everywhere, because the new keyword does not work with arrow function it only works with classes and functions if we use new keyword with an arrow function, we’ll see the following error if you try to do so:

const temp3=()=>{ this.val="a"}
const myObj3= new temp3();
console.log(myObj3)
// please try this in your browser console

“temp3 is not a constructor.” This is likely to discourage use of making function constructors directly, and to prefer use of the class keyword.

To conclude ✔️ JavaScript provides powerful object-oriented features, but we should use them with intent and understanding. JavaScript provides many powerful functional features as well, which are well worth looking into.