What is the 'new' keyword in JavaScript?
It does 5 things:
- It creates a new object. The type of this object is simply object.
- 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).
- It makes the
this
variable point to the newly created object. - It executes the constructor function, using the newly created object whenever
this
is mentioned. - 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:
- Functions created using the
function
keyword (excluding generator functions) - Classes (which can be treated as functions)
- Bound function exotic objects ("bound functions")
- Some host objects
- 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):
- A new object
o
is created - The
[[Prototype]]
("the prototype") ofo
is set to the value of the.prototype
property of the constructor (note this means the.constructor
property is inherited by the new object) - The target (ie
this
) of the constructor body is set too
- The constructor is run with the
this
value defined above - 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:
Create a new object
Add
__proto__
property on the newly created object that points toFruit.prototype
object.Point
this
inside theFruit
constructor to the newly created object.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
Web-Scraping JavaScript Page With Python
Is There an "Exists" Function For Jquery
Get Image Data Url in JavaScript
Difference Between a Function Expression VS Declaration in JavaScript
How to Detect If Multiple Keys Are Pressed At Once Using JavaScript
Checking If a Key Exists in a JavaScript Object
How to Get Hex Color Value Rather Than Rgb Value
In JavaScript, Does It Make a Difference If I Call a Function With Parentheses
Validate Decimal Numbers in JavaScript - Isnumeric()
When Should I Use Double or Single Quotes in JavaScript
How to Update Nested State Properties in React
Uploading Both Data and Files in One Form Using Ajax
How to Parse CSV Data With JavaScript