Related
The new keyword in JavaScript can be quite confusing when it is first encountered, as people tend to think that JavaScript is not an object-oriented programming language.
What is it?
What problems does it solve?
When is it appropriate and when not?
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 get or set 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 just `{}`. 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.
Suppose you have this function:
var Foo = function(){
this.A = 1;
this.B = 2;
};
If you call this as a stand-alone function like so:
Foo();
Executing this function will add two properties to the window object (A and B). It adds it to the window because window is the object that called the function when you execute it like that, and this in a function is the object that called the function. In JavaScript at least.
Now, call it like this with new:
var bar = new Foo();
When you add new to a function call, a new object is created (just var bar = new Object()) and the this within the function points to the new Object you just created, instead of to the object that called the function. So bar is now an object with the properties A and B. Any function can be a constructor; it just doesn't always make sense.
In addition to Daniel Howard's answer, here is what new does (or at least seems to do):
function New(func) {
var res = {};
if (func.prototype !== null) {
res.__proto__ = func.prototype;
}
var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
return ret;
}
return res;
}
While
var obj = New(A, 1, 2);
is equivalent to
var obj = new A(1, 2);
For beginners to understand it better
Try out the following code in the browser console.
function Foo() {
return this;
}
var a = Foo(); // Returns the 'window' object
var b = new Foo(); // Returns an empty object of foo
a instanceof Window; // True
a instanceof Foo; // False
b instanceof Window; // False
b instanceof Foo; // True
Now you can read the community wiki answer :)
so it's probably not for creating
instances of object
It's used exactly for that. You define a function constructor like so:
function Person(name) {
this.name = name;
}
var john = new Person('John');
However the extra benefit that ECMAScript has is you can extend with the .prototype property, so we can do something like...
Person.prototype.getName = function() { return this.name; }
All objects created from this constructor will now have a getName because of the prototype chain that they have access to.
JavaScript is an object-oriented programming language and it's used exactly for creating instances. It's prototype-based, rather than class-based, but that does not mean that it is not object-oriented.
Summary:
The new keyword is used in JavaScript to create a object from a constructor function. The new keyword has to be placed before the constructor function call and will do the following things:
Creates a new object
Sets the prototype of this object to the constructor function's prototype property
Binds the this keyword to the newly created object and executes the constructor function
Returns the newly created object
Example:
function Dog (age) {
this.age = age;
}
const doggie = new Dog(12);
console.log(doggie);
console.log(Object.getPrototypeOf(doggie) === Dog.prototype) // true
What exactly happens:
const doggie says: We need memory for declaring a variable.
The assignment operator = says: We are going to initialize this variable with the expression after the =
The expression is new Dog(12). The JavaScript engine sees the new keyword, creates a new object and sets the prototype to Dog.prototype
The constructor function is executed with the this value set to the new object. In this step is where the age is assigned to the new created doggie object.
The newly created object is returned and assigned to the variable doggie.
Please take a look at my observation on case III below. It is about what happens when you have an explicit return statement in a function which you are newing up. Have a look at the below cases:
Case I:
var Foo = function(){
this.A = 1;
this.B = 2;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1
Above is a plain case of calling the anonymous function pointed by variable Foo. When you call this function it returns undefined. Since there isn’t any explicit return statement, the JavaScript interpreter forcefully inserts a return undefined; statement at the end of the function. So the above code sample is equivalent to:
var Foo = function(){
this.A = 1;
this.B = 2;
return undefined;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1
When Foo function is invoked window is the default invocation object (contextual this) which gets new A and B properties.
Case II:
var Foo = function(){
this.A = 1;
this.B = 2;
};
var bar = new Foo();
console.log(bar()); //illegal isn't pointing to a function but an object
console.log(bar.A); //prints 1
Here the JavaScript interpreter, seeing the new keyword, creates a new object which acts as the invocation object (contextual this) of anonymous function pointed by Foo. In this case A and B become properties on the newly created object (in place of window object). Since you don't have any explicit return statement, JavaScript interpreter forcefully inserts a return statement to return the new object created due to usage of new keyword.
Case III:
var Foo = function(){
this.A = 1;
this.B = 2;
return {C:20,D:30};
};
var bar = new Foo();
console.log(bar.C);//prints 20
console.log(bar.A); //prints undefined. bar is not pointing to the object which got created due to new keyword.
Here again, the JavaScript interpreter, seeing the new keyword, creates a new object which acts as the invocation object (contextual this) of anonymous function pointed by Foo. Again, A and B become properties on the newly created object. But this time you have an explicit return statement so JavaScript interpreter will not do anything of its own.
The thing to note in case III is that the object being created due to new keyword got lost from your radar. bar is actually pointing to a completely different object which is not the one which JavaScript interpreter created due to the new keyword.
Quoting David Flanagan from JavaScript: The Definitive Guide (6th Edition), Chapter 4, Page # 62:
When an object creation expression is evaluated, JavaScript first
creates a new empty object, just like the one created by the object
initializer {}. Next, it invokes the specified function with the
specified arguments, passing the new object as the value of the this
keyword. The function can then use this to initialize the properties
of the newly created object. Functions written for use as constructors
do not return a value, and the value of the object creation expression
is the newly created and initialized object. If a constructor does
return an object value, that value becomes the value of the object
creation expression and the newly created object is discarded.
Additional information:
The functions used in the code snippet of the above cases have special names in the JavaScript world as below:
Case #
Name
Case I
Constructor function
Case II
Constructor function
Case III
Factory function
You can read about the difference between constructor functions and factory functions in this thread.
Code smell in case III - Factory functions should not be used with the new keyword which I've shown in the code snippet above. I've done so deliberately only to explain the concept.
JavaScript is a dynamic programming language which supports the object-oriented programming paradigm, and it is used for creating new instances of objects.
Classes are not necessary for objects. JavaScript is a prototype-based language.
The new keyword changes the context under which the function is being run and returns a pointer to that context.
When you don't use the new keyword, the context under which function Vehicle() runs is the same context from which you are calling the Vehicle function. The this keyword will refer to the same context. When you use new Vehicle(), a new context is created so the keyword this inside the function refers to the new context. What you get in return is the newly created context.
Sometimes code is easier than words:
var func1 = function (x) { this.x = x; } // Used with 'new' only
var func2 = function (x) { var z={}; z.x = x; return z; } // Used both ways
func1.prototype.y = 11;
func2.prototype.y = 12;
A1 = new func1(1); // Has A1.x AND A1.y
A2 = func1(1); // Undefined ('this' refers to 'window')
B1 = new func2(2); // Has B1.x ONLY
B2 = func2(2); // Has B2.x ONLY
For me, as long as I do not prototype, I use the style of func2 as it gives me a bit more flexibility inside and outside the function.
Every function has a prototype object that’s automatically set as the prototype of the objects created with that function.
You guys can check easily:
const a = { name: "something" };
console.log(a.prototype); // 'undefined' because it is not directly accessible
const b = function () {
console.log("somethign");
};
console.log(b.prototype); // Returns b {}
But every function and objects has the __proto__ property which points to the prototype of that object or function. __proto__ and prototype are two different terms. I think we can make this comment: "Every object is linked to a prototype via the proto" But __proto__ does not exist in JavaScript. This property is added by browser just to help for debugging.
console.log(a.__proto__); // Returns {}
console.log(b.__proto__); // Returns [Function]
You guys can check this on the terminal easily. So what is a constructor function?
function CreateObject(name, age) {
this.name = name;
this.age = age
}
Five things that pay attention first:
When the constructor function is invoked with new, the function’s internal [[Construct]] method is called to create a new instance object and allocate memory.
We are not using return keyword. new will handle it.
The name of the function is capitalized, so when developers see your code they can understand that they have to use the new keyword.
We do not use the arrow function. Because the value of the this parameter is picked up at the moment that the arrow function is created which is "window". Arrow functions are lexically scoped, not dynamically. Lexically here means locally. The arrow function carries its local "this" value.
Unlike regular functions, arrow functions can never be called with the new keyword, because they do not have the [[Construct]] method. The prototype property also does not exist for arrow functions.
const me = new CreateObject("yilmaz", "21")
new invokes the function and then creates an empty object {} and then adds "name" key with the value of "name", and "age" key with the value of argument "age".
When we invoke a function, a new execution context is created with "this" and "arguments", and that is why "new" has access to these arguments.
By default, this inside the constructor function will point to the "window" object, but new changes it. "this" points to the empty object {} that is created and then properties are added to newly created object. If you had any variable that defined without "this" property will no be added to the object.
function CreateObject(name, age) {
this.name = name;
this.age = age;
const myJob = "developer"
}
myJob property will not added to the object because there is nothing referencing to the newly created object.
const me = {name: "yilmaz", age: 21} // There isn't any 'myJob' key
In the beginning I said every function has a "prototype" property, including constructor functions. We can add methods to the prototype of the constructor, so every object that created from that function will have access to it.
CreateObject.prototype.myActions = function() { /* Define something */ }
Now "me" object can use the "myActions" method.
JavaScript has built-in constructor functions: Function, Boolean, Number, String, etc.
If I create
const a = new Number(5);
console.log(a); // [Number: 5]
console.log(typeof a); // object
Anything that is created by using new has the type of object. Now "a" has access all of the methods that are stored inside Number.prototype. If I defined
const b = 5;
console.log(a === b); // 'false'
a and b are 5 but a is object and b is primitive. Even though b is primitive type, when it is created, JavaScript automatically wraps it with Number(), so b has access to all of the methods that inside Number.prototype.
A constructor function is useful when you want to create multiple similar objects with the same properties and methods. That way you will not be allocating extra memory so your code will run more efficiently.
The new keyword is for creating new object instances. And yes, JavaScript is a dynamic programming language, which supports the object-oriented programming paradigm. The convention about the object naming is: always use a capital letter for objects that are supposed to be instantiated by the new keyword.
obj = new Element();
JavaScript is not an object-oriented programming (OOP) language. Therefore the look up process in JavaScript works using a delegation process, also known as prototype delegation or prototypical inheritance.
If you try to get the value of a property from an object that it doesn't have, the JavaScript engine looks to the object's prototype (and its prototype, one step above at a time).
It's prototype chain until the chain ends up to null which is Object.prototype == null (Standard Object Prototype).
At this point, if the property or method is not defined then undefined is returned.
Important! Functions are are first-class objects.
Functions = Function + Objects Combo
FunctionName.prototype = { shared SubObject }
{
// other properties
prototype: {
// shared space which automatically gets [[prototype]] linkage
when "new" keyword is used on creating instance of "Constructor
Function"
}
}
Thus with the new keyword, some of the task that were manually done, e.g.,
Manual object creation, e.g., newObj.
Hidden bond creation using proto (AKA: dunder proto) in the JavaScript specification [[prototype]] (i.e., proto)
referencing and assign properties to newObj
return of the newObj object.
All is done manually.
function CreateObj(value1, value2) {
const newObj = {};
newObj.property1 = value1;
newObj.property2 = value2;
return newObj;
}
var obj = CreateObj(10,20);
obj.__proto__ === Object.prototype; // true
Object.getPrototypeOf(obj) === Object.prototype // true
JavaScript keyword new helps to automate this process:
A new object literal is created identified by this:{}
referencing and assign properties to this
Hidden bond creation [[prototype]] (i.e. proto) to Function.prototype shared space.
implicit return of this object {}
function CreateObj(value1, value2) {
this.property1 = value1;
this.property2 = value2;
}
var obj = new CreateObj(10,20);
obj.__proto__ === CreateObj.prototype // true
Object.getPrototypeOf(obj) == CreateObj.prototype // true
Calling a constructor function without the new keyword:
=> this: Window
function CreateObj(value1, value2) {
var isWindowObj = this === window;
console.log("Is Pointing to Window Object", isWindowObj);
this.property1 = value1;
this.property2 = value2;
}
var obj = new CreateObj(10,20); // Is Pointing to Window Object false
var obj = CreateObj(10,20); // Is Pointing to Window Object true
window.property1; // 10
window.property2; // 20
The new keyword creates instances of objects using functions as a constructor. For instance:
var Foo = function() {};
Foo.prototype.bar = 'bar';
var foo = new Foo();
foo instanceof Foo; // true
Instances inherit from the prototype of the constructor function. So given the example above...
foo.bar; // 'bar'
Well, JavaScript per se can differ greatly from platform to platform as it is always an implementation of the original specification ECMAScript (ES).
In any case, independently of the implementation, all JavaScript implementations that follow the ECMAScript specification right, will give you an object-oriented language. According to the ES standard:
ECMAScript is an object-oriented programming language for
performing computations and manipulating computational objects
within a host environment.
So now that we have agreed that JavaScript is an implementation of ECMAScript and therefore it is an object-oriented language. The definition of the new operation in any object-oriented language, says that such a keyword is used to create an object instance from a class of a certain type (including anonymous types, in cases like C#).
In ECMAScript we don't use classes, as you can read from the specifications:
ECMAScript does not use classes such as those in C++, Smalltalk, or Java. Instead objects may be created in various ways including via
a literal notation or via constructors which create objects and then execute code that initializes all or part of them by assigning initial
values to their properties. Each constructor is a function that has a
property named ―
prototype ‖ that is used to implement prototype - based inheritance and shared properties. Objects are created by
using constructors in new expressions; for example, new
Date(2009,11) creates a new Date object. Invoking a constructor
without using new has consequences that depend on the constructor.
For example, Date() produces a string representation of the
current date and time rather than an object.
It has 3 stages:
1.Create: It creates a new object, and sets this object's [[prototype]] property to be the prototype property of the constructor function.
2.Execute: It makes this point to the newly created object and executes the constructor function.
3.Return: In normal case, it will return the newly created object. However, if you explicitly return a non-null object or a function , this value is returned instead. To be mentioned, if you return a non-null value, but it is not an object(such as Symbol value, undefined, NaN), this value is ignored and the newly created object is returned.
function myNew(constructor, ...args) {
const obj = {}
Object.setPrototypeOf(obj, constructor.prototype)
const returnedVal = constructor.apply(obj, args)
if (
typeof returnedVal === 'function'
|| (typeof returnedVal === 'object' && returnedVal !== null)) {
return returnedVal
}
return obj
}
For more info and the tests for myNew, you can read my blog: https://medium.com/#magenta2127/how-does-the-new-operator-work-f7eaac692026
The new keyword in JavaScript can be quite confusing when it is first encountered, as people tend to think that JavaScript is not an object-oriented programming language.
What is it?
What problems does it solve?
When is it appropriate and when not?
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 get or set 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 just `{}`. 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.
Suppose you have this function:
var Foo = function(){
this.A = 1;
this.B = 2;
};
If you call this as a stand-alone function like so:
Foo();
Executing this function will add two properties to the window object (A and B). It adds it to the window because window is the object that called the function when you execute it like that, and this in a function is the object that called the function. In JavaScript at least.
Now, call it like this with new:
var bar = new Foo();
When you add new to a function call, a new object is created (just var bar = new Object()) and the this within the function points to the new Object you just created, instead of to the object that called the function. So bar is now an object with the properties A and B. Any function can be a constructor; it just doesn't always make sense.
In addition to Daniel Howard's answer, here is what new does (or at least seems to do):
function New(func) {
var res = {};
if (func.prototype !== null) {
res.__proto__ = func.prototype;
}
var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
return ret;
}
return res;
}
While
var obj = New(A, 1, 2);
is equivalent to
var obj = new A(1, 2);
For beginners to understand it better
Try out the following code in the browser console.
function Foo() {
return this;
}
var a = Foo(); // Returns the 'window' object
var b = new Foo(); // Returns an empty object of foo
a instanceof Window; // True
a instanceof Foo; // False
b instanceof Window; // False
b instanceof Foo; // True
Now you can read the community wiki answer :)
so it's probably not for creating
instances of object
It's used exactly for that. You define a function constructor like so:
function Person(name) {
this.name = name;
}
var john = new Person('John');
However the extra benefit that ECMAScript has is you can extend with the .prototype property, so we can do something like...
Person.prototype.getName = function() { return this.name; }
All objects created from this constructor will now have a getName because of the prototype chain that they have access to.
JavaScript is an object-oriented programming language and it's used exactly for creating instances. It's prototype-based, rather than class-based, but that does not mean that it is not object-oriented.
Summary:
The new keyword is used in JavaScript to create a object from a constructor function. The new keyword has to be placed before the constructor function call and will do the following things:
Creates a new object
Sets the prototype of this object to the constructor function's prototype property
Binds the this keyword to the newly created object and executes the constructor function
Returns the newly created object
Example:
function Dog (age) {
this.age = age;
}
const doggie = new Dog(12);
console.log(doggie);
console.log(Object.getPrototypeOf(doggie) === Dog.prototype) // true
What exactly happens:
const doggie says: We need memory for declaring a variable.
The assignment operator = says: We are going to initialize this variable with the expression after the =
The expression is new Dog(12). The JavaScript engine sees the new keyword, creates a new object and sets the prototype to Dog.prototype
The constructor function is executed with the this value set to the new object. In this step is where the age is assigned to the new created doggie object.
The newly created object is returned and assigned to the variable doggie.
Please take a look at my observation on case III below. It is about what happens when you have an explicit return statement in a function which you are newing up. Have a look at the below cases:
Case I:
var Foo = function(){
this.A = 1;
this.B = 2;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1
Above is a plain case of calling the anonymous function pointed by variable Foo. When you call this function it returns undefined. Since there isn’t any explicit return statement, the JavaScript interpreter forcefully inserts a return undefined; statement at the end of the function. So the above code sample is equivalent to:
var Foo = function(){
this.A = 1;
this.B = 2;
return undefined;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1
When Foo function is invoked window is the default invocation object (contextual this) which gets new A and B properties.
Case II:
var Foo = function(){
this.A = 1;
this.B = 2;
};
var bar = new Foo();
console.log(bar()); //illegal isn't pointing to a function but an object
console.log(bar.A); //prints 1
Here the JavaScript interpreter, seeing the new keyword, creates a new object which acts as the invocation object (contextual this) of anonymous function pointed by Foo. In this case A and B become properties on the newly created object (in place of window object). Since you don't have any explicit return statement, JavaScript interpreter forcefully inserts a return statement to return the new object created due to usage of new keyword.
Case III:
var Foo = function(){
this.A = 1;
this.B = 2;
return {C:20,D:30};
};
var bar = new Foo();
console.log(bar.C);//prints 20
console.log(bar.A); //prints undefined. bar is not pointing to the object which got created due to new keyword.
Here again, the JavaScript interpreter, seeing the new keyword, creates a new object which acts as the invocation object (contextual this) of anonymous function pointed by Foo. Again, A and B become properties on the newly created object. But this time you have an explicit return statement so JavaScript interpreter will not do anything of its own.
The thing to note in case III is that the object being created due to new keyword got lost from your radar. bar is actually pointing to a completely different object which is not the one which JavaScript interpreter created due to the new keyword.
Quoting David Flanagan from JavaScript: The Definitive Guide (6th Edition), Chapter 4, Page # 62:
When an object creation expression is evaluated, JavaScript first
creates a new empty object, just like the one created by the object
initializer {}. Next, it invokes the specified function with the
specified arguments, passing the new object as the value of the this
keyword. The function can then use this to initialize the properties
of the newly created object. Functions written for use as constructors
do not return a value, and the value of the object creation expression
is the newly created and initialized object. If a constructor does
return an object value, that value becomes the value of the object
creation expression and the newly created object is discarded.
Additional information:
The functions used in the code snippet of the above cases have special names in the JavaScript world as below:
Case #
Name
Case I
Constructor function
Case II
Constructor function
Case III
Factory function
You can read about the difference between constructor functions and factory functions in this thread.
Code smell in case III - Factory functions should not be used with the new keyword which I've shown in the code snippet above. I've done so deliberately only to explain the concept.
JavaScript is a dynamic programming language which supports the object-oriented programming paradigm, and it is used for creating new instances of objects.
Classes are not necessary for objects. JavaScript is a prototype-based language.
The new keyword changes the context under which the function is being run and returns a pointer to that context.
When you don't use the new keyword, the context under which function Vehicle() runs is the same context from which you are calling the Vehicle function. The this keyword will refer to the same context. When you use new Vehicle(), a new context is created so the keyword this inside the function refers to the new context. What you get in return is the newly created context.
Sometimes code is easier than words:
var func1 = function (x) { this.x = x; } // Used with 'new' only
var func2 = function (x) { var z={}; z.x = x; return z; } // Used both ways
func1.prototype.y = 11;
func2.prototype.y = 12;
A1 = new func1(1); // Has A1.x AND A1.y
A2 = func1(1); // Undefined ('this' refers to 'window')
B1 = new func2(2); // Has B1.x ONLY
B2 = func2(2); // Has B2.x ONLY
For me, as long as I do not prototype, I use the style of func2 as it gives me a bit more flexibility inside and outside the function.
Every function has a prototype object that’s automatically set as the prototype of the objects created with that function.
You guys can check easily:
const a = { name: "something" };
console.log(a.prototype); // 'undefined' because it is not directly accessible
const b = function () {
console.log("somethign");
};
console.log(b.prototype); // Returns b {}
But every function and objects has the __proto__ property which points to the prototype of that object or function. __proto__ and prototype are two different terms. I think we can make this comment: "Every object is linked to a prototype via the proto" But __proto__ does not exist in JavaScript. This property is added by browser just to help for debugging.
console.log(a.__proto__); // Returns {}
console.log(b.__proto__); // Returns [Function]
You guys can check this on the terminal easily. So what is a constructor function?
function CreateObject(name, age) {
this.name = name;
this.age = age
}
Five things that pay attention first:
When the constructor function is invoked with new, the function’s internal [[Construct]] method is called to create a new instance object and allocate memory.
We are not using return keyword. new will handle it.
The name of the function is capitalized, so when developers see your code they can understand that they have to use the new keyword.
We do not use the arrow function. Because the value of the this parameter is picked up at the moment that the arrow function is created which is "window". Arrow functions are lexically scoped, not dynamically. Lexically here means locally. The arrow function carries its local "this" value.
Unlike regular functions, arrow functions can never be called with the new keyword, because they do not have the [[Construct]] method. The prototype property also does not exist for arrow functions.
const me = new CreateObject("yilmaz", "21")
new invokes the function and then creates an empty object {} and then adds "name" key with the value of "name", and "age" key with the value of argument "age".
When we invoke a function, a new execution context is created with "this" and "arguments", and that is why "new" has access to these arguments.
By default, this inside the constructor function will point to the "window" object, but new changes it. "this" points to the empty object {} that is created and then properties are added to newly created object. If you had any variable that defined without "this" property will no be added to the object.
function CreateObject(name, age) {
this.name = name;
this.age = age;
const myJob = "developer"
}
myJob property will not added to the object because there is nothing referencing to the newly created object.
const me = {name: "yilmaz", age: 21} // There isn't any 'myJob' key
In the beginning I said every function has a "prototype" property, including constructor functions. We can add methods to the prototype of the constructor, so every object that created from that function will have access to it.
CreateObject.prototype.myActions = function() { /* Define something */ }
Now "me" object can use the "myActions" method.
JavaScript has built-in constructor functions: Function, Boolean, Number, String, etc.
If I create
const a = new Number(5);
console.log(a); // [Number: 5]
console.log(typeof a); // object
Anything that is created by using new has the type of object. Now "a" has access all of the methods that are stored inside Number.prototype. If I defined
const b = 5;
console.log(a === b); // 'false'
a and b are 5 but a is object and b is primitive. Even though b is primitive type, when it is created, JavaScript automatically wraps it with Number(), so b has access to all of the methods that inside Number.prototype.
A constructor function is useful when you want to create multiple similar objects with the same properties and methods. That way you will not be allocating extra memory so your code will run more efficiently.
The new keyword is for creating new object instances. And yes, JavaScript is a dynamic programming language, which supports the object-oriented programming paradigm. The convention about the object naming is: always use a capital letter for objects that are supposed to be instantiated by the new keyword.
obj = new Element();
JavaScript is not an object-oriented programming (OOP) language. Therefore the look up process in JavaScript works using a delegation process, also known as prototype delegation or prototypical inheritance.
If you try to get the value of a property from an object that it doesn't have, the JavaScript engine looks to the object's prototype (and its prototype, one step above at a time).
It's prototype chain until the chain ends up to null which is Object.prototype == null (Standard Object Prototype).
At this point, if the property or method is not defined then undefined is returned.
Important! Functions are are first-class objects.
Functions = Function + Objects Combo
FunctionName.prototype = { shared SubObject }
{
// other properties
prototype: {
// shared space which automatically gets [[prototype]] linkage
when "new" keyword is used on creating instance of "Constructor
Function"
}
}
Thus with the new keyword, some of the task that were manually done, e.g.,
Manual object creation, e.g., newObj.
Hidden bond creation using proto (AKA: dunder proto) in the JavaScript specification [[prototype]] (i.e., proto)
referencing and assign properties to newObj
return of the newObj object.
All is done manually.
function CreateObj(value1, value2) {
const newObj = {};
newObj.property1 = value1;
newObj.property2 = value2;
return newObj;
}
var obj = CreateObj(10,20);
obj.__proto__ === Object.prototype; // true
Object.getPrototypeOf(obj) === Object.prototype // true
JavaScript keyword new helps to automate this process:
A new object literal is created identified by this:{}
referencing and assign properties to this
Hidden bond creation [[prototype]] (i.e. proto) to Function.prototype shared space.
implicit return of this object {}
function CreateObj(value1, value2) {
this.property1 = value1;
this.property2 = value2;
}
var obj = new CreateObj(10,20);
obj.__proto__ === CreateObj.prototype // true
Object.getPrototypeOf(obj) == CreateObj.prototype // true
Calling a constructor function without the new keyword:
=> this: Window
function CreateObj(value1, value2) {
var isWindowObj = this === window;
console.log("Is Pointing to Window Object", isWindowObj);
this.property1 = value1;
this.property2 = value2;
}
var obj = new CreateObj(10,20); // Is Pointing to Window Object false
var obj = CreateObj(10,20); // Is Pointing to Window Object true
window.property1; // 10
window.property2; // 20
The new keyword creates instances of objects using functions as a constructor. For instance:
var Foo = function() {};
Foo.prototype.bar = 'bar';
var foo = new Foo();
foo instanceof Foo; // true
Instances inherit from the prototype of the constructor function. So given the example above...
foo.bar; // 'bar'
Well, JavaScript per se can differ greatly from platform to platform as it is always an implementation of the original specification ECMAScript (ES).
In any case, independently of the implementation, all JavaScript implementations that follow the ECMAScript specification right, will give you an object-oriented language. According to the ES standard:
ECMAScript is an object-oriented programming language for
performing computations and manipulating computational objects
within a host environment.
So now that we have agreed that JavaScript is an implementation of ECMAScript and therefore it is an object-oriented language. The definition of the new operation in any object-oriented language, says that such a keyword is used to create an object instance from a class of a certain type (including anonymous types, in cases like C#).
In ECMAScript we don't use classes, as you can read from the specifications:
ECMAScript does not use classes such as those in C++, Smalltalk, or Java. Instead objects may be created in various ways including via
a literal notation or via constructors which create objects and then execute code that initializes all or part of them by assigning initial
values to their properties. Each constructor is a function that has a
property named ―
prototype ‖ that is used to implement prototype - based inheritance and shared properties. Objects are created by
using constructors in new expressions; for example, new
Date(2009,11) creates a new Date object. Invoking a constructor
without using new has consequences that depend on the constructor.
For example, Date() produces a string representation of the
current date and time rather than an object.
It has 3 stages:
1.Create: It creates a new object, and sets this object's [[prototype]] property to be the prototype property of the constructor function.
2.Execute: It makes this point to the newly created object and executes the constructor function.
3.Return: In normal case, it will return the newly created object. However, if you explicitly return a non-null object or a function , this value is returned instead. To be mentioned, if you return a non-null value, but it is not an object(such as Symbol value, undefined, NaN), this value is ignored and the newly created object is returned.
function myNew(constructor, ...args) {
const obj = {}
Object.setPrototypeOf(obj, constructor.prototype)
const returnedVal = constructor.apply(obj, args)
if (
typeof returnedVal === 'function'
|| (typeof returnedVal === 'object' && returnedVal !== null)) {
return returnedVal
}
return obj
}
For more info and the tests for myNew, you can read my blog: https://medium.com/#magenta2127/how-does-the-new-operator-work-f7eaac692026
The new keyword in JavaScript can be quite confusing when it is first encountered, as people tend to think that JavaScript is not an object-oriented programming language.
What is it?
What problems does it solve?
When is it appropriate and when not?
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 get or set 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 just `{}`. 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.
Suppose you have this function:
var Foo = function(){
this.A = 1;
this.B = 2;
};
If you call this as a stand-alone function like so:
Foo();
Executing this function will add two properties to the window object (A and B). It adds it to the window because window is the object that called the function when you execute it like that, and this in a function is the object that called the function. In JavaScript at least.
Now, call it like this with new:
var bar = new Foo();
When you add new to a function call, a new object is created (just var bar = new Object()) and the this within the function points to the new Object you just created, instead of to the object that called the function. So bar is now an object with the properties A and B. Any function can be a constructor; it just doesn't always make sense.
In addition to Daniel Howard's answer, here is what new does (or at least seems to do):
function New(func) {
var res = {};
if (func.prototype !== null) {
res.__proto__ = func.prototype;
}
var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
return ret;
}
return res;
}
While
var obj = New(A, 1, 2);
is equivalent to
var obj = new A(1, 2);
For beginners to understand it better
Try out the following code in the browser console.
function Foo() {
return this;
}
var a = Foo(); // Returns the 'window' object
var b = new Foo(); // Returns an empty object of foo
a instanceof Window; // True
a instanceof Foo; // False
b instanceof Window; // False
b instanceof Foo; // True
Now you can read the community wiki answer :)
so it's probably not for creating
instances of object
It's used exactly for that. You define a function constructor like so:
function Person(name) {
this.name = name;
}
var john = new Person('John');
However the extra benefit that ECMAScript has is you can extend with the .prototype property, so we can do something like...
Person.prototype.getName = function() { return this.name; }
All objects created from this constructor will now have a getName because of the prototype chain that they have access to.
JavaScript is an object-oriented programming language and it's used exactly for creating instances. It's prototype-based, rather than class-based, but that does not mean that it is not object-oriented.
Summary:
The new keyword is used in JavaScript to create a object from a constructor function. The new keyword has to be placed before the constructor function call and will do the following things:
Creates a new object
Sets the prototype of this object to the constructor function's prototype property
Binds the this keyword to the newly created object and executes the constructor function
Returns the newly created object
Example:
function Dog (age) {
this.age = age;
}
const doggie = new Dog(12);
console.log(doggie);
console.log(Object.getPrototypeOf(doggie) === Dog.prototype) // true
What exactly happens:
const doggie says: We need memory for declaring a variable.
The assignment operator = says: We are going to initialize this variable with the expression after the =
The expression is new Dog(12). The JavaScript engine sees the new keyword, creates a new object and sets the prototype to Dog.prototype
The constructor function is executed with the this value set to the new object. In this step is where the age is assigned to the new created doggie object.
The newly created object is returned and assigned to the variable doggie.
Please take a look at my observation on case III below. It is about what happens when you have an explicit return statement in a function which you are newing up. Have a look at the below cases:
Case I:
var Foo = function(){
this.A = 1;
this.B = 2;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1
Above is a plain case of calling the anonymous function pointed by variable Foo. When you call this function it returns undefined. Since there isn’t any explicit return statement, the JavaScript interpreter forcefully inserts a return undefined; statement at the end of the function. So the above code sample is equivalent to:
var Foo = function(){
this.A = 1;
this.B = 2;
return undefined;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1
When Foo function is invoked window is the default invocation object (contextual this) which gets new A and B properties.
Case II:
var Foo = function(){
this.A = 1;
this.B = 2;
};
var bar = new Foo();
console.log(bar()); //illegal isn't pointing to a function but an object
console.log(bar.A); //prints 1
Here the JavaScript interpreter, seeing the new keyword, creates a new object which acts as the invocation object (contextual this) of anonymous function pointed by Foo. In this case A and B become properties on the newly created object (in place of window object). Since you don't have any explicit return statement, JavaScript interpreter forcefully inserts a return statement to return the new object created due to usage of new keyword.
Case III:
var Foo = function(){
this.A = 1;
this.B = 2;
return {C:20,D:30};
};
var bar = new Foo();
console.log(bar.C);//prints 20
console.log(bar.A); //prints undefined. bar is not pointing to the object which got created due to new keyword.
Here again, the JavaScript interpreter, seeing the new keyword, creates a new object which acts as the invocation object (contextual this) of anonymous function pointed by Foo. Again, A and B become properties on the newly created object. But this time you have an explicit return statement so JavaScript interpreter will not do anything of its own.
The thing to note in case III is that the object being created due to new keyword got lost from your radar. bar is actually pointing to a completely different object which is not the one which JavaScript interpreter created due to the new keyword.
Quoting David Flanagan from JavaScript: The Definitive Guide (6th Edition), Chapter 4, Page # 62:
When an object creation expression is evaluated, JavaScript first
creates a new empty object, just like the one created by the object
initializer {}. Next, it invokes the specified function with the
specified arguments, passing the new object as the value of the this
keyword. The function can then use this to initialize the properties
of the newly created object. Functions written for use as constructors
do not return a value, and the value of the object creation expression
is the newly created and initialized object. If a constructor does
return an object value, that value becomes the value of the object
creation expression and the newly created object is discarded.
Additional information:
The functions used in the code snippet of the above cases have special names in the JavaScript world as below:
Case #
Name
Case I
Constructor function
Case II
Constructor function
Case III
Factory function
You can read about the difference between constructor functions and factory functions in this thread.
Code smell in case III - Factory functions should not be used with the new keyword which I've shown in the code snippet above. I've done so deliberately only to explain the concept.
JavaScript is a dynamic programming language which supports the object-oriented programming paradigm, and it is used for creating new instances of objects.
Classes are not necessary for objects. JavaScript is a prototype-based language.
The new keyword changes the context under which the function is being run and returns a pointer to that context.
When you don't use the new keyword, the context under which function Vehicle() runs is the same context from which you are calling the Vehicle function. The this keyword will refer to the same context. When you use new Vehicle(), a new context is created so the keyword this inside the function refers to the new context. What you get in return is the newly created context.
Sometimes code is easier than words:
var func1 = function (x) { this.x = x; } // Used with 'new' only
var func2 = function (x) { var z={}; z.x = x; return z; } // Used both ways
func1.prototype.y = 11;
func2.prototype.y = 12;
A1 = new func1(1); // Has A1.x AND A1.y
A2 = func1(1); // Undefined ('this' refers to 'window')
B1 = new func2(2); // Has B1.x ONLY
B2 = func2(2); // Has B2.x ONLY
For me, as long as I do not prototype, I use the style of func2 as it gives me a bit more flexibility inside and outside the function.
Every function has a prototype object that’s automatically set as the prototype of the objects created with that function.
You guys can check easily:
const a = { name: "something" };
console.log(a.prototype); // 'undefined' because it is not directly accessible
const b = function () {
console.log("somethign");
};
console.log(b.prototype); // Returns b {}
But every function and objects has the __proto__ property which points to the prototype of that object or function. __proto__ and prototype are two different terms. I think we can make this comment: "Every object is linked to a prototype via the proto" But __proto__ does not exist in JavaScript. This property is added by browser just to help for debugging.
console.log(a.__proto__); // Returns {}
console.log(b.__proto__); // Returns [Function]
You guys can check this on the terminal easily. So what is a constructor function?
function CreateObject(name, age) {
this.name = name;
this.age = age
}
Five things that pay attention first:
When the constructor function is invoked with new, the function’s internal [[Construct]] method is called to create a new instance object and allocate memory.
We are not using return keyword. new will handle it.
The name of the function is capitalized, so when developers see your code they can understand that they have to use the new keyword.
We do not use the arrow function. Because the value of the this parameter is picked up at the moment that the arrow function is created which is "window". Arrow functions are lexically scoped, not dynamically. Lexically here means locally. The arrow function carries its local "this" value.
Unlike regular functions, arrow functions can never be called with the new keyword, because they do not have the [[Construct]] method. The prototype property also does not exist for arrow functions.
const me = new CreateObject("yilmaz", "21")
new invokes the function and then creates an empty object {} and then adds "name" key with the value of "name", and "age" key with the value of argument "age".
When we invoke a function, a new execution context is created with "this" and "arguments", and that is why "new" has access to these arguments.
By default, this inside the constructor function will point to the "window" object, but new changes it. "this" points to the empty object {} that is created and then properties are added to newly created object. If you had any variable that defined without "this" property will no be added to the object.
function CreateObject(name, age) {
this.name = name;
this.age = age;
const myJob = "developer"
}
myJob property will not added to the object because there is nothing referencing to the newly created object.
const me = {name: "yilmaz", age: 21} // There isn't any 'myJob' key
In the beginning I said every function has a "prototype" property, including constructor functions. We can add methods to the prototype of the constructor, so every object that created from that function will have access to it.
CreateObject.prototype.myActions = function() { /* Define something */ }
Now "me" object can use the "myActions" method.
JavaScript has built-in constructor functions: Function, Boolean, Number, String, etc.
If I create
const a = new Number(5);
console.log(a); // [Number: 5]
console.log(typeof a); // object
Anything that is created by using new has the type of object. Now "a" has access all of the methods that are stored inside Number.prototype. If I defined
const b = 5;
console.log(a === b); // 'false'
a and b are 5 but a is object and b is primitive. Even though b is primitive type, when it is created, JavaScript automatically wraps it with Number(), so b has access to all of the methods that inside Number.prototype.
A constructor function is useful when you want to create multiple similar objects with the same properties and methods. That way you will not be allocating extra memory so your code will run more efficiently.
The new keyword is for creating new object instances. And yes, JavaScript is a dynamic programming language, which supports the object-oriented programming paradigm. The convention about the object naming is: always use a capital letter for objects that are supposed to be instantiated by the new keyword.
obj = new Element();
JavaScript is not an object-oriented programming (OOP) language. Therefore the look up process in JavaScript works using a delegation process, also known as prototype delegation or prototypical inheritance.
If you try to get the value of a property from an object that it doesn't have, the JavaScript engine looks to the object's prototype (and its prototype, one step above at a time).
It's prototype chain until the chain ends up to null which is Object.prototype == null (Standard Object Prototype).
At this point, if the property or method is not defined then undefined is returned.
Important! Functions are are first-class objects.
Functions = Function + Objects Combo
FunctionName.prototype = { shared SubObject }
{
// other properties
prototype: {
// shared space which automatically gets [[prototype]] linkage
when "new" keyword is used on creating instance of "Constructor
Function"
}
}
Thus with the new keyword, some of the task that were manually done, e.g.,
Manual object creation, e.g., newObj.
Hidden bond creation using proto (AKA: dunder proto) in the JavaScript specification [[prototype]] (i.e., proto)
referencing and assign properties to newObj
return of the newObj object.
All is done manually.
function CreateObj(value1, value2) {
const newObj = {};
newObj.property1 = value1;
newObj.property2 = value2;
return newObj;
}
var obj = CreateObj(10,20);
obj.__proto__ === Object.prototype; // true
Object.getPrototypeOf(obj) === Object.prototype // true
JavaScript keyword new helps to automate this process:
A new object literal is created identified by this:{}
referencing and assign properties to this
Hidden bond creation [[prototype]] (i.e. proto) to Function.prototype shared space.
implicit return of this object {}
function CreateObj(value1, value2) {
this.property1 = value1;
this.property2 = value2;
}
var obj = new CreateObj(10,20);
obj.__proto__ === CreateObj.prototype // true
Object.getPrototypeOf(obj) == CreateObj.prototype // true
Calling a constructor function without the new keyword:
=> this: Window
function CreateObj(value1, value2) {
var isWindowObj = this === window;
console.log("Is Pointing to Window Object", isWindowObj);
this.property1 = value1;
this.property2 = value2;
}
var obj = new CreateObj(10,20); // Is Pointing to Window Object false
var obj = CreateObj(10,20); // Is Pointing to Window Object true
window.property1; // 10
window.property2; // 20
The new keyword creates instances of objects using functions as a constructor. For instance:
var Foo = function() {};
Foo.prototype.bar = 'bar';
var foo = new Foo();
foo instanceof Foo; // true
Instances inherit from the prototype of the constructor function. So given the example above...
foo.bar; // 'bar'
Well, JavaScript per se can differ greatly from platform to platform as it is always an implementation of the original specification ECMAScript (ES).
In any case, independently of the implementation, all JavaScript implementations that follow the ECMAScript specification right, will give you an object-oriented language. According to the ES standard:
ECMAScript is an object-oriented programming language for
performing computations and manipulating computational objects
within a host environment.
So now that we have agreed that JavaScript is an implementation of ECMAScript and therefore it is an object-oriented language. The definition of the new operation in any object-oriented language, says that such a keyword is used to create an object instance from a class of a certain type (including anonymous types, in cases like C#).
In ECMAScript we don't use classes, as you can read from the specifications:
ECMAScript does not use classes such as those in C++, Smalltalk, or Java. Instead objects may be created in various ways including via
a literal notation or via constructors which create objects and then execute code that initializes all or part of them by assigning initial
values to their properties. Each constructor is a function that has a
property named ―
prototype ‖ that is used to implement prototype - based inheritance and shared properties. Objects are created by
using constructors in new expressions; for example, new
Date(2009,11) creates a new Date object. Invoking a constructor
without using new has consequences that depend on the constructor.
For example, Date() produces a string representation of the
current date and time rather than an object.
It has 3 stages:
1.Create: It creates a new object, and sets this object's [[prototype]] property to be the prototype property of the constructor function.
2.Execute: It makes this point to the newly created object and executes the constructor function.
3.Return: In normal case, it will return the newly created object. However, if you explicitly return a non-null object or a function , this value is returned instead. To be mentioned, if you return a non-null value, but it is not an object(such as Symbol value, undefined, NaN), this value is ignored and the newly created object is returned.
function myNew(constructor, ...args) {
const obj = {}
Object.setPrototypeOf(obj, constructor.prototype)
const returnedVal = constructor.apply(obj, args)
if (
typeof returnedVal === 'function'
|| (typeof returnedVal === 'object' && returnedVal !== null)) {
return returnedVal
}
return obj
}
For more info and the tests for myNew, you can read my blog: https://medium.com/#magenta2127/how-does-the-new-operator-work-f7eaac692026
What's the difference between these 2 implementations of prototypal inheritance, and considering that we're working with 2 different "prototypes" (the prototype property that's only on functions, and the internal prototype), and how do these implementations differ in their prototype chain lookup? Also, does the first implementation (using the prototype property) rely on our use of the new operator?
Assigning to a functions's prototype property and using the new operator:
function foo() {}
foo.prototype.output = function(){
console.log('inherits from Function.prototype property');
};
bar = new foo();
bar.output();
Storing a function in an object literal and using the Object.create() method:
var foo = {
output: function(){
console.log('inherits from the internal prototype');
}
};
var bar = Object.create(foo);
bar.output();
The main difference is in the way it is used, and the dangers associated.
The first one forces you to use new when you want to create a new object. The syntax is fairly ugly (SomeConstructor.prototype.method), and it bears one major flaw: calling a constructor which adds properties (this.name = nameParam...) without new will apply the construction to the global object. The behaviour of the constructor is weird (create new object which delegates to SomeConstructor.prototype, then apply the constructor to the new object, then if the constructor returns something replace the object by the something). Plus, in your example, foo itself is not usable, you have to create a new object in order to access its functionalities.
The second one, Object.create, doesn't force you to use any syntoxic quirk. You don't have the global pollution risk. The object foo has functionalities that can already be used without creating a new object, and bar will simply borrow these functionalities. This kind of pattern can also make it easier to implement factories (without news to replace everywhere) and object pools if needed.
Eric Eliott talks about it very well, and Kyle Simpson wrote a whole book about prototype delegation!
Now, here's how the lookup happens:
With the constructor, the lookup is done on Constructor.prototype (not the actual internal prototype of the constructor, but its prototypeproperty. If you find it confusing, congratulations, you are human). Additional properties are set in the constructor function. foo itself is not used for the lookup, foo.prototype (again, not the same as foo.__proto__ which points to Function) is the one used for it.
With Object.create the lookup is done on the object itself (foo). There's no prototype non-prototype property on the object.
There's very funny diagrams on this page of Kyle Simpson's book which explain the thing further.
More on new in this question: Is JavaScript's "new" keyword considered harmful?
OK, first of all, in case you didn't know, Object.create is based upon the following pattern proposed by Douglas Crockford (read more here):
function create (proto) {
function f () {}
f.prototype = proto;
return new f();
}
Now, you must be aware that the above code does not yield the same result in case you pass null as parameter.
The ECMAScript algorithm for creating new objects (read more here) states that if the prototype of a function is set to null (or any non object), when you're trying to use new f() syntax, the newly created object will inherit from Object.prototype.
If you use Object.create(null), the newly created object will have its [[Prototype]] internal member set to null, which means the prototype chain will stop there (your object doesn't get hasOwnProperty and other stuff from Object.prototype as normal object would).
var o1 = create(null);
var o2 = Object.create(null);
Object.getPrototypeOf(o1) === Object.prototype // true
Object.getPrototypeOf(o2) === Object.prototype // false
Object.getPrototypeOf(o2) === null // true
The first example - foo, is a function.
The second example - foo is an object.
in the second example, bar becomes an new instance without a constructor.
See - https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/create, to add the constructor.
As a side note, it common best practice that constructors should begin with a capital letter.
I am just learning Javascript and I was wondering, is using the prototype declaration, like this:
function TSomeObj()
{
this.name="my object";
}
TSomeObj.prototype.showname = function() {
alert(this.name);
}
Basically the same as doing it like this:
function TSomeObj()
{
this.name="my object";
this.showname = function() {
alert(this.name);
}
}
When I dump the object's properties I get the same result:
TSomeObj (inline version) =
{
'name': 'my object',
'test': function
}
TSomeObj (prototype declaration) =
{
'name': 'my object',
'test': function
}
What exactly is the benefit of using prototype declarations? Except less cluttering and more orderly sourcecode perhaps.
Update: I should perhaps have made it more clear that it was the final result i was curious about. The end result is ofcourse the same (i.e both register a new function in the object prototype) - but the way they do it is wildly different. Thank you for all replies and info!
Note: This answer is accurate but does not fully reflect the new way to create classes in JavaScript using the ES6 class Thing {} syntax. Everything here does in fact apply to ES6 classes, but might take some translation.
I initially answered the wrong question. Here is the answer to your actually-asked question. I'll leave my other notes in just in case they're helpful to someone.
Adding properties to an object in the constructor function through this.prop is different from doing so outside through Object.prototype.prop.
The most important difference is that when you add a property to the prototype of a function and instantiate a new object from it, that property is accessed in the new object by stepping up the inheritance chain rather than it being directly on the object.
var baseobj = {};
function ObjType1() {
this.prop = 2;
}
function ObjType2() {}
ObjType1.prototype = baseobj;
ObjType2.prototype = baseobj; // these now have the *same* prototype object.
ObjType1.prototype.prop = 1;
// identical to `baseobj.prop = 1` -- we're modifying the prototype
var a = new ObjType1(),
b = new ObjType2();
//a.hasOwnProperty('prop') : true
//b.hasOwnProperty('prop') : false -- it has no local property "prop"
//a: { prop = 2 }, b : { prop = 1 } -- b's "prop" comes from the inheritance chain
baseobj.prop = 3;
//b's value changed because we changed the prototype
//a: { prop = 2 }, b : { prop = 3 }
delete a.prop;
//a is now reflecting the prototype's "prop" instead of its own:
//a: { prop = 3 }, b : { prop = 3 }
A second difference is that adding properties to a prototype occurs once when that code executes, but adding properties to the object inside the constructor occurs each time a new object is created. This means using the prototype performs better and uses less memory, because no new storage is required until you set that same property on the leaf/proximate object.
Another difference is that internally-added functions have access to private variables and functions (those declared in the constructor with var, const, or let), and prototype-based or externally-added functions do not, simply because they have the wrong scope:
function Obj(initialx, initialy) {
var x = initialx,
y = initialy;
this.getX = function() {
return x;
}
var twoX = function() { // mostly identical to `function twoX() { ... }`
return x * 2;
}
this.getTwoX = function() {
return twoX();
}
}
Obj.prototype.getY = function() {
return y; // fails, even if you try `this.y`
}
Obj.prototype.twoY = function() {
return y * 2; // fails
}
Obj.prototype.getTwoY = function() {
return twoY(); // fails
}
var obj = new Obj();
// obj.y : fails, you can't access "y", it is internal
// obj.twoX() : fails, you can't access "twoX", it is internal
// obj.getTwoX() : works, it is "public" but has access to the twoX function
General notes about JavaScript objects, functions, and inheritance
All non-string and non-scalar variables in JavaScript are objects. (And some primitive types undergo boxing when a method is used on them such as true.toString() or 1.2.valueOf()). They all act somewhat like a hash/dictionary in that they have an unlimited(?) number of key/value pairs that can be assigned to them. The current list of primitives in JavaScript is: string, number, bigint, boolean, undefined, symbol, null.
Each object has an inheritance chain of "prototypes" that go all the way up to the base object. When you access a property of an object, if that property doesn't exist on the object itself, then the secret prototype of that object is checked, and if not present then that object's prototype, so on and so forth all the way up. Some browsers expose this prototype through the property __proto__. The more modern way to get the prototype of an object is Object.getPrototypeOf(obj). Regular objects don't have a prototype property because this property is for functions, to store the object that will be the prototype of any new objects created using that function as their constructor.
A JavaScript function is a special case of an object, that in addition to having the key/value pairs of an object also has parameters and a series of statements that are executed in order.
Every time a function object is invoked it is paired with another object that is accessed from within the function by the keyword this. Usually, the this object is the one that the function is a property of. For example, ''.replace() boxes the string literal to a String, then inside the replace function, this refers to that object. another example is when a function is attached to a DOM element (perhaps an onclick function on a button), then this refers to the DOM element. You can manually choose the paired this object dynamically using apply or call.
When a JavaScript function is invoked with the new keyword as in var obj = new Obj(), this causes a special thing to happen. If you don't specifically return anything, then instead of obj now containing the return value of the Obj function, it contains the this object that was paired with the function at invocation time, which will be a new empty object with the first parent in its inheritance chain set to Obj.prototype. The invoked Obj() function, while running, can modify the properties of the new object. Then that object is returned.
You don't have to worry much about the keyword constructor, just suffice it to say that obj.constructor points to the Obj function (so you can find the thing that created it), but you'll probably not need to use this for most things.
Back to your question. To understand the difference between modifying the properties of an object from within the constructor and modifying its prototype, try this:
var baseobj = {prop1: 'x'};
function TSomeObj() {
this.prop2 = 'y';
};
TSomeObj.prototype = baseobj;
var a = new TSomeObj();
//now dump the properties of `a`
a.prop1 = 'z';
baseobj.prop1 = 'w';
baseobj.prop2 = 'q';
//dump properties of `a` again
delete a.prop1;
//dump properties of `a` again
You'll see that setting a.prop1 is actually creating a new property of the proximate object, but it doesn't overwrite the base object's prop1. When you remove prop1 from a then you get the inherited prop1 that we changed. Also, even though we added prop2 after a was created, a still has that property. This is because javascript uses prototype inheritance rather than classic inheritance. When you modify the prototype of TSomeObj you also modify all its previously-instantiated objects because they are actively inheriting from it.
When you instantiate a class in any programing language, the new object takes on the properties of its "constructor" class (which we usually think of as synonymous with the object). And in most programming languages, you can't change the properties or methods of the class or the instantiated object, except by stopping your program and changing the class declaration.
Javascript, though, lets you modify the properties of objects and "classes" at run-time, and all instantiated objects of that type class are also modified unless they have their own properties that override the modification. Objects can beget objects which can beget objects, so this works in a chain all the way up to the base Object class. I put "classes" in quotes because there really isn't such a thing as a class in JavaScript (even in ES6, it's mostly syntactic sugar), except that the new keyword lets you make new objects with the inheritance chain hooked up for you, so we call them classes even though they're just the result of constructor functions being called with the new keyword.
Some other notes: functions have a Function constructor, objects have an Object constructor. The prototype of the Function constructor is (surprise, surprise) Object.
Inheriting from an object without the constructor function running
In some cases, it's useful to be able to create a new "instance of an object" without the constructor function running. You can inherit from a class without running the class's constructor function like so (almost like manually doing child.__proto__ = parent):
function inheritFrom(Class) {
function F() {};
F.prototype = Class.prototype;
return new F();
}
A better way to do this now is Object.setPrototypeOf().
The accepted answer missed the most important distinctions between prototypes and methods bound to a specific object, so I'm going to clarify
Prototype'd functions are only ever declared once. Functions attached using
this.method = function(){}
are redeclared again and again whenever you create an instance of the class. Prototypes are, thus, generally the preferred way to attach functions to a class since they use less memory since every instance of that class uses the same functions. As Erik pointed out, however, functions attached using prototypes vs attached to a specific object have a different scope, so prototypes don't have access to "private" variables defined in a function constructor.
As for what a prototype actually is, since it's an odd concept coming from traditional OO languages:
Whenever you create a new instance of a function:
var obj = new Foo();
the following logic is run (not literally this code, but something similar):
var inheritsFrom = Foo,
objectInstance = {};
objectInstance.__proto__ = inheritsFrom.prototype;
inheritsFrom.apply( objectInstance, arguments );
return objectInstance;
so:
A new object is created, {}, to represent the new instance of the function
The prototype of the function is copied to __proto__ of the new object. Note that this is a copy-by-reference, so Foo.prototype and objectInstance.__proto__ now refer to the same object and changes made in one can be seen in the other immediately.
The function is called with this new object being set as this in the function
and whenever you try to access a function or property, e.g.: obj.bar(), the following logic gets run:
if( obj.hasOwnProperty('bar') ) {
// use obj.bar
} else if( obj.__proto__ ){
var proto = obj.__proto__;
while(proto){
if( proto.hasOwnProperty('bar') ){
// use proto.bar;
}
proto = proto.__proto__;
}
}
in other words, the following are checked:
obj.bar
obj.__proto__.bar
obj.__proto__.__proto__.bar
obj.__proto__.__proto__.__proto__.bar
... etc
until __proto__ eventually equals null because you've reached the end of the prototype chain.
Many browsers actually expose __proto__ now, so you can inspect it in Firebug or the Console in Chrome/Safari. IE doesn't expose it (and may very well have a different name for the same thing internally).