What Is the 'New' Keyword in JavaScript

What is the 'new' keyword in JavaScript?

It does 5 things:

  1. It creates a new object. The type of this object is simply object.
  2. It sets this new object's internal, inaccessible, [[prototype]] (i.e. __proto__) property to be the constructor function's external, accessible, prototype object (every function object automatically has a prototype property).
  3. It makes the this variable point to the newly created object.
  4. It executes the constructor function, using the newly created object whenever this is mentioned.
  5. It returns the newly created object, unless the constructor function returns a non-null object reference. In this case, that object reference is returned instead.

Note: constructor function refers to the function after the new keyword, as in

new ConstructorFunction(arg1, arg2)

Once this is done, if an undefined property of the new object is requested, the script will check the object's [[prototype]] object for the property instead. This is how you can get something similar to traditional class inheritance in JavaScript.

The most difficult part about this is point number 2. Every object (including functions) has this internal property called [[prototype]]. It can only be set at object creation time, either with new, with Object.create, or based on the literal (functions default to Function.prototype, numbers to Number.prototype, etc.). It can only be read with Object.getPrototypeOf(someObject). There is no other way to set or read this value.

Functions, in addition to the hidden [[prototype]] property, also have a property called prototype, and it is this that you can access, and modify, to provide inherited properties and methods for the objects you make.


Here is an example:

ObjMaker = function() {this.a = 'first';};
// ObjMaker is just a function, there's nothing special about it that makes
// it a constructor.

ObjMaker.prototype.b = 'second';
// like all functions, ObjMaker has an accessible prototype property that
// we can alter. I just added a property called 'b' to it. Like
// all objects, ObjMaker also has an inaccessible [[prototype]] property
// that we can't do anything with

obj1 = new ObjMaker();
// 3 things just happened.
// A new, empty object was created called obj1. At first obj1 was the same
// as {}. The [[prototype]] property of obj1 was then set to the current
// object value of the ObjMaker.prototype (if ObjMaker.prototype is later
// assigned a new object value, obj1's [[prototype]] will not change, but you
// can alter the properties of ObjMaker.prototype to add to both the
// prototype and [[prototype]]). The ObjMaker function was executed, with
// obj1 in place of this... so obj1.a was set to 'first'.

obj1.a;
// returns 'first'
obj1.b;
// obj1 doesn't have a property called 'b', so JavaScript checks
// its [[prototype]]. Its [[prototype]] is the same as ObjMaker.prototype
// ObjMaker.prototype has a property called 'b' with value 'second'
// returns 'second'

It's like class inheritance because now, any objects you make using new ObjMaker() will also appear to have inherited the 'b' property.

If you want something like a subclass, then you do this:

SubObjMaker = function () {};
SubObjMaker.prototype = new ObjMaker(); // note: this pattern is deprecated!
// Because we used 'new', the [[prototype]] property of SubObjMaker.prototype
// is now set to the object value of ObjMaker.prototype.
// The modern way to do this is with Object.create(), which was added in ECMAScript 5:
// SubObjMaker.prototype = Object.create(ObjMaker.prototype);

SubObjMaker.prototype.c = 'third';
obj2 = new SubObjMaker();
// [[prototype]] property of obj2 is now set to SubObjMaker.prototype
// Remember that the [[prototype]] property of SubObjMaker.prototype
// is ObjMaker.prototype. So now obj2 has a prototype chain!
// obj2 ---> SubObjMaker.prototype ---> ObjMaker.prototype

obj2.c;
// returns 'third', from SubObjMaker.prototype

obj2.b;
// returns 'second', from ObjMaker.prototype

obj2.a;
// returns 'first', from SubObjMaker.prototype, because SubObjMaker.prototype
// was created with the ObjMaker function, which assigned a for us

I read a ton of rubbish on this subject before finally finding this page, where this is explained very well with nice diagrams.

Javascript new keyword

No, this does not create a new instance of Person and then call a method on it. It creates an instance of whatever Person.doSomething() is. So, in effect, you these two are equivalent:

const Person = {

doSomething: function(foo, bar){

this.foo = foo;

this.bar = bar;

}

}

//create a new instance of `Person.doSomething`

const p1 = new Person.doSomething(1, "one");

//take a reference of `Person.doSomething`

const temp = Person.doSomething;

//create an instance of it

const p2 = new temp(2, "two");

console.log("p1:", p1);

console.log("p1 instanceof Person.doSomething:", p1 instanceof Person.doSomething);

console.log("p2:", p2);

console.log("p2 instanceof Person.doSomething:", p2 instanceof Person.doSomething);

javascript: what do the new keywords do internally

The new-able objects in JavaScript are:

  1. Functions created using the function keyword (excluding generator functions)
  2. Classes (which can be treated as functions)
  3. Bound function exotic objects ("bound functions")
  4. Some host objects
  5. Proxies if they are applied to one of the above

I know this because the only object types the new operator works with are "constructors" (specification term). A constructor is an object with a [[Construct]] internal method, and you can search the ECMAScript specification to find out which kinds of object have a [[Construct]] internal method.

To make the result of a constructor function new-able, therefore, you must return one of the object kinds listed above.

Note that the specification specifically says that all constructors are definitionally functions because they must support the [[Call]] internal method (note also the caveat below about host objects).

If you want to get very advanced, then you may be interested to learn that host objects do not appear to share the ordinary limitations for constructors (presumably for legacy Web compatibility reasons), but these are exceptional.

Explanation of the .constructor property

When a new-able function f is declared, two objects are created: the function-object f itself, and a default object on the .prototype own-property of f. The .constructor property of this default .prototype object is automatically set by the runtime to be f. I believe classes work in a very similar fashion. Note that the fact that the name of this property was chosen to be "prototype" makes discussing prototypes quite confusing in JavaScript (as it is distinct from the [[prototype]] of the function).

This constructor own-property on the object positioned on the .prototype property, is never read by any built-in function or operation (that I know of). I view it as vestigial from the earliest days of JavaScript - it's original intent was as a way to maintain a link between the "class" that constructed an object as a developer affordance. Host environments (eg browsers) sometimes use it to infer the "type" of an object for the purposes of communicating with the user (eg. console output), the property is writeable and therefore unreliable.

Steps performed by the new operator

At a high level, when new is invoked against a constructor, the following steps occur (spec contains full details):

  1. A new object o is created
  2. The [[Prototype]] ("the prototype") of o is set to the value of the .prototype property of the constructor (note this means the .constructor property is inherited by the new object)
  3. The target (ie this) of the constructor body is set to o
  4. The constructor is run with the this value defined above
  5. If there is no explicit object-type return value, then o is returned by default

Omitting 'new' keyword causing unexplainable problems in javascript constructor function

Value of this depends on how the function is called.

In non-strict mode, when you call the altFruit function without the new keyword, this inside it will refer to the global window object. So,

this.person = person;

will add person property on the global window object. (you can test this by logging window.person on the console at the end of your code).

When you call aFunction, in non-strict mode, value of this inside displayInfo function will refer to the global window object.

In short, your code is adding and reading properties to and from the global window object, respectively.

The "new" operator

new operator is used to create instances of user-defined object types (like Fruit) or built-in object types (like Array, Date, etc).

When you call new Fruit(...), new operator will do the following things:

  1. Create a new object

  2. Add __proto__ property on the newly created object that points to Fruit.prototype object.

  3. Point this inside the Fruit constructor to the newly created object.

  4. Return the newly created object from the Fruit constructor function.

For more details, see: MDN: new operator

What is the alternative to using the 'new' keyword in javascript?

This is another option:

var car1 = {make: "nissan", model: "gtr",year: "1999" }

You can also create an empty car(make\year\model will be undefined) like this:

var car1 = {};

or

var car1 = new car();

You can later fill it up with:

car1.make = "nissan";


Related Topics



Leave a reply



Submit