JS: “new” operator

By Xah Lee. Date: . Last updated: .

The keyword new is a operator.

It's used to create new object, like this:

new functionName(body);

Here is a typical use:

// example of creating a object with user defined constructor

// define a function.
// This is the constructor
function Burger(meat_val, cheese_val) {
 this.meat = meat_val;
 this.cheese = cheese_val;
 // must not contain return statement
}

// create a new object
const xobj = new Burger(3, 4);

console.log(xobj);
// Burger { meat: 3, cheese: 4 }

Functions designed to be used with new are called constructor, and by convention the first letter of the function name is capitalized.

[see What is Constructor?]

What does “new” do exactly?

Here is what the new keyword do. Let's say we have new Burger().

  1. Every function has a property key "prototype".
  2. The value of Burger.prototype by default is {"constructor":Burger} (that is, a object with a property key "constructor", with value of the function itself).
  3. JavaScript creates a new empty object newObj, and make newObj's parent to be Burger.prototype.
  4. The function Burger is executed, with Burger's this having value of newObj.
  5. If Burger does not have a return statement, or it does but returns a value that is not an object, then the newObj is the result. If Burger returns a value that is a JavaScript object, then that object is the result.
// example showing difference of constructor with different type of return value

const Burger1 = function () {
 this.b = 4;
};

const Burger2 = function () {
 this.b = 4;
 return 3;
};

const Burger3 = function () {
 this.b = 4;
 return { "c": 7 };
};

const x1 = new Burger1();
const x2 = new Burger2();
const x3 = new Burger3();

console.log(x1);
// Burger1 { b: 4 }

console.log(x2);
// Burger2 { b: 4 }

console.log(x3);
// { c: 7 }

// what 「new Burger()」 returns depends on whether Burger returns a object

What is the parent of a object created with “new”?

// showing the prototype of a object created by a constructor that doesn't have a return statement

const Burger = function (xx) {
  this.yy = xx;
};

const jj = new Burger(3);
console.log(Reflect.getPrototypeOf(jj) === Burger.prototype);
// showing the prototype of a object created by a constructor that returns a object

const xdad = { "yy": 3 };

// this function returns a object
const Burger = function (xx) {
 return xdad;
};

const jj = new Burger(3);

console.assert(xdad === jj);

// the parent of jj is not Burger.prototype
console.assert(Reflect.getPrototypeOf(jj) === Burger.prototype === false);

console.assert(Reflect.getPrototypeOf(jj) === Object.prototype);

[see Prototype and Inheritance]

Changing Constructor's Property key “prototype” Does Not Change Parent of Existing Object

// changing constructor's prototype property does not change parent of existing object

const jj = { xx: 5 };

function Burger() {}

Burger.prototype = jj;

const aa = new Burger();

console.assert(Reflect.getPrototypeOf(aa) === jj);

Burger.prototype = { yy: 6 };

console.assert(Reflect.getPrototypeOf(aa) === jj);