What is returned from a constructor? - javascript

If I return some value or object in constructor function, what will the var get?
function MyConstroctor()
{
//what in case when return 5;
//what in case when return someObject;
}
var n = new MyConstroctor();
what n will get in both cases?
Actually its a quiz question, what will be the answer?
What is returned from a custom object constructor?
a)The newly-instantiated object
b)undefined - constructors do not return values
c)Whatever is the return statement
d)Whatever is the return statement; the newly-instantiated object if no return statement

Short Answer
The constructor returns the this object.
function Car() {
this.num_wheels = 4;
}
// car = { num_wheels:4 };
var car = new Car();
Long Answer
By the Javascript spec, when a function is invoked with new, Javascript creates a new object, then sets the "constructor" property of that object to the function invoked, and finally assigns that object to the name this. You then have access to the this object from the body of the function.
Once the function body is executed, Javascript will return:
ANY object if the type of the returned value is object:
function Car(){
this.num_wheels = 4;
return { num_wheels:37 };
}
var car = new Car();
alert(car.num_wheels); // 37
The this object if the function has no return statement OR if the function returns a value of a type other than object:
function Car() {
this.num_wheels = 4;
return 'VROOM';
}
var car = new Car();
alert(car.num_wheels); // 4
alert(Car()); // No 'new', so the alert will show 'VROOM'

Basically if your constructor returns a primitive value, such as a string, number, boolean, null or undefined, (or you don't return anything which is equivalent to returning undefined), a newly created object that inherits from the constructor's prototype will be returned.
That's the object you have access with the this keyword inside the constructor when called with the new keyword.
For example:
function Test() {
return 5; // returning a primitive
}
var obj = new Test();
obj == 5; // false
obj instanceof Test; // true, it inherits from Test.prototype
Test.prototype.isPrototypeOf(obj); // true
But if the returned value is an object reference, that will be the returned value, e.g.:
function Test2() {
this.foo = ""; // the object referred by `this` will be lost...
return {foo: 'bar'};
}
var obj = new Test2();
obj.foo; // "bar"
If you are interested on the internals of the new operator, you can check the algorithm of the [[Construct]] internal operation, is the one responsible of creating the new object that inherits from the constructor's prototype, and to decide what to return:
13.2.2 [[Construct]]
When the [[Construct]] internal method for a Function object F is called with a possibly empty list of arguments, the following steps are taken:
Let obj be a newly created native ECMAScript object.
Set all the internal methods of obj as specified in 8.12.
Set the [[Class]] internal property of obj to "Object".
Set the [[Extensible]] internal property of obj to true.
Let proto be the value of calling the [[Get]] internal property of F with argument "prototype".
If Type(proto) is Object, set the[[Prototype]]` internal property of obj to proto.
If Type(proto) is not Object, set the [[Prototype]] internal property of obj to the standard built-in Object prototype object as described in 15.2.4.
Let result be the result of calling the [[Call]] internal property of F, providing obj as the this value and providing the argument list passed into [[Construct]] as args.
If Type(result) is Object then return result.
Return obj.

I found this great link:
JavaScript: Constructor Return Value
The second piece of magic eluded to above is the ability for a
constructor to return a specific, possibly pre-existing object, rather
than a reference to a new instance. This would allow you to manage the
number of actual instances yourself if needed; possibly for reasons of
limited resources or whatnot.
var g_deebee = new Deebee();
function Deebee() { return g_deebee; }
var db1 = new Deebee();
var db2 = new Deebee();
if (db1 != db2)
throw Error("JS constructor returned wrong object!");
else console.log('Equal');

It's as easy as it said in documentation (new operator) :
The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)

Trying to simplify the existing answers by providing discrete examples proving that:
Only constructors that return primitive or undefined implicitly create a new instance of themselves. Otherwise the exact object returned by the constructor is used as is.
Consider the following constructor that returns exactly what we pass to it. Check the usages:
//A constructor returning the passed value, or not returning at all.
function MyConstructor(obj){
if(obj!==undefined){
return obj;
}
//else do not call return
}
//no value passed (no value is returned from constructor)
console.log((new MyConstructor()) instanceof MyConstructor)
//true
//Primitive passed:
console.log((new MyConstructor(1)) instanceof MyConstructor)
//true
console.log((new MyConstructor(false)) instanceof MyConstructor)
//true
console.log((new MyConstructor("1")) instanceof MyConstructor)
//true
console.log((new MyConstructor(1.0)) instanceof MyConstructor)
//true
//Object passed
console.log((new MyConstructor(new Number(1))) instanceof MyConstructor)
//false
console.log((new MyConstructor({num:1})) instanceof MyConstructor)
//false
console.log((new MyConstructor([1])) instanceof MyConstructor)
//false
console.log((new MyConstructor(MyConstructor)) instanceof MyConstructor)
//false
//Same results if we use: MyConstructor.prototype.isPrototypeOf(new MyConstructor()) e.t.c..
The same rules as above apply also for class constructors. This means that, if the constructor does not return undefined or primitive, we can have the following, which might feel weird to people coming from java:
(new MyClass()) instanceof MyClass //false
Using the same constructor, check in practice how the instance is different when undefined or primitive is returned:
//As above
function MyConstructor(obj){
if(obj!==undefined){
return obj;
}
//else do not call return
}
//Same object passed (same instance to both variables)
let obj = {};
let a1 = new MyConstructor(obj)
let a2 = new MyConstructor(obj)
a1.x=1
a2.x=2
console.log(a1.x === a2.x, a1.x, a2.x)
//true 2 2
//undefined passed (different instance to each variable)
let b1 = new MyConstructor()
let b2 = new MyConstructor()
b1.x=1
b2.x=2
console.log(b1.x === b2.x, b1.x, b2.x)
//false 1 2
//Primitive passed (different instance to each variable)
let c1 = new MyConstructor(5)
let c2 = new MyConstructor(5)
c1.x=1
c2.x=2
console.log(c1.x === c2.x, c1.x, c2.x)
//false 1 2
Additional note: Sometimes a function could act as a constructor even if it is not called as a constructor:
function F(){
//If not called as a constructor, call as a constructor and return the result
if(!new.target){
return new F();
}
}
console.log(F() instanceof F)
//true
console.log(new F() instanceof F)
//true

You shouldn't return anything in a constructor. A constructor is used to initialize the object. In case you want to know what happens is that if you return 5 then n will simply be an empty object and if you return for example { a: 5 }, then n will have a property a=5.

To answer your specific question:
function MyConstructor()
{
return 5;
}
var n = new MyConstructor();
n is an object instance of MyConstructor.
function SomeObject(name) {
this.name = name;
this.shout = function() {
alert("Hello " + this.name)
}
}
function MyConstructor()
{
return new SomeObject("coure06");
}
var n = new MyConstructor();
n.shout();
n is an instance of SomeObject (call n.shout() to prove it)
To make this all absolutely clear...
1) If you return a primitive type, like a number or a string, it will be ignored.
2) Otherwise, you will pass back the object
Functions and constructors are exactly the same in JavaScript, but how you call them changes their behaviour. A quick example of this is below...
function AddTwoNumbers(first, second) {
return first + second;
}
var functionCall = AddTwoNumbers(5, 3);
alert(functionCall);// 8
var constructorCall = new AddTwoNumbers(5, 3);
alert(constructorCall);// object

Related

Javascript Function Strange Behavior [duplicate]

What are the exact circumstances for which a return statement in Javascript can return a value other than this when a constructor is invoked using the new keyword?
Example:
function Foo () {
return something;
}
var foo = new Foo ();
If I'm not mistaken, if something is a non-function primitive, this will be returned. Otherwise something is returned. Is this correct?
In other words, what values can something take to cause (new Foo () instanceof Foo) === false?
The exact condition is described on the [[Construct]] internal property, which is used by the new operator:
From the ECMA-262 3rd. Edition Specification:
13.2.2 [[Construct]]
When the [[Construct]] property for a Function object F is
called, the following steps are taken:
Create a new native ECMAScript object.
Set the [[Class]] property of Result(1) to "Object".
Get the value of the prototype property of F.
If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3).
If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as
described in 15.2.3.1.
Invoke the [[Call]] property of F, providing Result(1) as the this value and
providing the argument list passed into [[Construct]] as the
argument values.
If Type(Result(6)) is
Object then return Result(6).
Return Result(1).
Look at steps 7 and 8, the new object will be returned only if the
type of Result(6) (the value returned from the F constructor
function) is not an Object.
Concrete examples
/*
ECMA 262 v 5
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
"4.3.2
primitive value
member of one of the types Undefined, Null, Boolean, Number, Symbol, or String as defined in clause 6"
*/
var Person = function(x){
return x;
};
console.log(Person.constructor);
console.log(Person.prototype.constructor);
console.log(typeof(Person));
console.log(typeof(Person.prototype));
function log(x){
console.log(x instanceof Person);
console.log(typeof x);
console.log(typeof x.prototype);
}
log(new Person(undefined));
log(new Person(null));
log(new Person(true));
log(new Person(2));
log(new Person(""));
//returns a function not an object
log(new Person(function(){}));
//implementation?
//log(new Person(Symbol('%')));
I couldn't find any documentation on the matter, but I think you're correct. For example, you can return new Number(5) from a constructor, but not the literal 5 (which is ignored and this is returned instead).
As a side note, the return value or this is just part of the equation.
For example, consider this:
function Two() { return new Number(2); }
var two = new Two;
two + 2; // 4
two.valueOf = function() { return 3; }
two + 2; // 5
two.valueOf = function() { return '2'; }
two + 2; // '22'
As you can see, .valueOf() is internally used and can be exploited for fun and profit. You can even create side effects, for example:
function AutoIncrementingNumber(start) {
var n = new Number, val = start || 0;
n.valueOf = function() { return val++; };
return n;
}
var auto = new AutoIncrementingNumber(42);
auto + 1; // 43
auto + 1; // 44
auto + 1; // 45
I can imagine this must have some sort of practical application. And it doesn't have to be explicitly a Number either, if you add .valueOf to any object it can behave as a number:
({valueOf: function() { return Math.random(); }}) + 1; // 1.6451723610516638
You can exploit this to make an object that always returns a new GUID, for instance.
Trying to put a few points in simpler words.
In javascript, when you use a new keyword on a function and if,
function does not return anything, it will return an intended object
function User() {
this.name = 'Virat'
}
var user = new User();
console.log(user.name); //=> 'Virat'
function returns any truthy complex object [object, array, function etc], that complex object takes priority and user variable will hold the returned complex object
function User() {
this.name = 'Virat';
return function(){};
}
var user = new User();
console.log(user.name); //=> undefined
console.log(user); //=> function
function returns any literal, constructor takes priority and it will return an intended object
function User() {
this.name = 'Virat';
return 10;
}
var user = new User();
console.log(user.name); //=> 'Virat'
When you are using the new keyword, an object is created. Then the function is called to initialise the object.
There is nothing that the function can do to prevent the object being created, as that is done before the function is called.

How come instance is not undefined [duplicate]

If I return some value or object in constructor function, what will the var get?
function MyConstroctor()
{
//what in case when return 5;
//what in case when return someObject;
}
var n = new MyConstroctor();
what n will get in both cases?
Actually its a quiz question, what will be the answer?
What is returned from a custom object constructor?
a)The newly-instantiated object
b)undefined - constructors do not return values
c)Whatever is the return statement
d)Whatever is the return statement; the newly-instantiated object if no return statement
Short Answer
The constructor returns the this object.
function Car() {
this.num_wheels = 4;
}
// car = { num_wheels:4 };
var car = new Car();
Long Answer
By the Javascript spec, when a function is invoked with new, Javascript creates a new object, then sets the "constructor" property of that object to the function invoked, and finally assigns that object to the name this. You then have access to the this object from the body of the function.
Once the function body is executed, Javascript will return:
ANY object if the type of the returned value is object:
function Car(){
this.num_wheels = 4;
return { num_wheels:37 };
}
var car = new Car();
alert(car.num_wheels); // 37
The this object if the function has no return statement OR if the function returns a value of a type other than object:
function Car() {
this.num_wheels = 4;
return 'VROOM';
}
var car = new Car();
alert(car.num_wheels); // 4
alert(Car()); // No 'new', so the alert will show 'VROOM'
Basically if your constructor returns a primitive value, such as a string, number, boolean, null or undefined, (or you don't return anything which is equivalent to returning undefined), a newly created object that inherits from the constructor's prototype will be returned.
That's the object you have access with the this keyword inside the constructor when called with the new keyword.
For example:
function Test() {
return 5; // returning a primitive
}
var obj = new Test();
obj == 5; // false
obj instanceof Test; // true, it inherits from Test.prototype
Test.prototype.isPrototypeOf(obj); // true
But if the returned value is an object reference, that will be the returned value, e.g.:
function Test2() {
this.foo = ""; // the object referred by `this` will be lost...
return {foo: 'bar'};
}
var obj = new Test2();
obj.foo; // "bar"
If you are interested on the internals of the new operator, you can check the algorithm of the [[Construct]] internal operation, is the one responsible of creating the new object that inherits from the constructor's prototype, and to decide what to return:
13.2.2 [[Construct]]
When the [[Construct]] internal method for a Function object F is called with a possibly empty list of arguments, the following steps are taken:
Let obj be a newly created native ECMAScript object.
Set all the internal methods of obj as specified in 8.12.
Set the [[Class]] internal property of obj to "Object".
Set the [[Extensible]] internal property of obj to true.
Let proto be the value of calling the [[Get]] internal property of F with argument "prototype".
If Type(proto) is Object, set the[[Prototype]]` internal property of obj to proto.
If Type(proto) is not Object, set the [[Prototype]] internal property of obj to the standard built-in Object prototype object as described in 15.2.4.
Let result be the result of calling the [[Call]] internal property of F, providing obj as the this value and providing the argument list passed into [[Construct]] as args.
If Type(result) is Object then return result.
Return obj.
I found this great link:
JavaScript: Constructor Return Value
The second piece of magic eluded to above is the ability for a
constructor to return a specific, possibly pre-existing object, rather
than a reference to a new instance. This would allow you to manage the
number of actual instances yourself if needed; possibly for reasons of
limited resources or whatnot.
var g_deebee = new Deebee();
function Deebee() { return g_deebee; }
var db1 = new Deebee();
var db2 = new Deebee();
if (db1 != db2)
throw Error("JS constructor returned wrong object!");
else console.log('Equal');
It's as easy as it said in documentation (new operator) :
The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)
Trying to simplify the existing answers by providing discrete examples proving that:
Only constructors that return primitive or undefined implicitly create a new instance of themselves. Otherwise the exact object returned by the constructor is used as is.
Consider the following constructor that returns exactly what we pass to it. Check the usages:
//A constructor returning the passed value, or not returning at all.
function MyConstructor(obj){
if(obj!==undefined){
return obj;
}
//else do not call return
}
//no value passed (no value is returned from constructor)
console.log((new MyConstructor()) instanceof MyConstructor)
//true
//Primitive passed:
console.log((new MyConstructor(1)) instanceof MyConstructor)
//true
console.log((new MyConstructor(false)) instanceof MyConstructor)
//true
console.log((new MyConstructor("1")) instanceof MyConstructor)
//true
console.log((new MyConstructor(1.0)) instanceof MyConstructor)
//true
//Object passed
console.log((new MyConstructor(new Number(1))) instanceof MyConstructor)
//false
console.log((new MyConstructor({num:1})) instanceof MyConstructor)
//false
console.log((new MyConstructor([1])) instanceof MyConstructor)
//false
console.log((new MyConstructor(MyConstructor)) instanceof MyConstructor)
//false
//Same results if we use: MyConstructor.prototype.isPrototypeOf(new MyConstructor()) e.t.c..
The same rules as above apply also for class constructors. This means that, if the constructor does not return undefined or primitive, we can have the following, which might feel weird to people coming from java:
(new MyClass()) instanceof MyClass //false
Using the same constructor, check in practice how the instance is different when undefined or primitive is returned:
//As above
function MyConstructor(obj){
if(obj!==undefined){
return obj;
}
//else do not call return
}
//Same object passed (same instance to both variables)
let obj = {};
let a1 = new MyConstructor(obj)
let a2 = new MyConstructor(obj)
a1.x=1
a2.x=2
console.log(a1.x === a2.x, a1.x, a2.x)
//true 2 2
//undefined passed (different instance to each variable)
let b1 = new MyConstructor()
let b2 = new MyConstructor()
b1.x=1
b2.x=2
console.log(b1.x === b2.x, b1.x, b2.x)
//false 1 2
//Primitive passed (different instance to each variable)
let c1 = new MyConstructor(5)
let c2 = new MyConstructor(5)
c1.x=1
c2.x=2
console.log(c1.x === c2.x, c1.x, c2.x)
//false 1 2
Additional note: Sometimes a function could act as a constructor even if it is not called as a constructor:
function F(){
//If not called as a constructor, call as a constructor and return the result
if(!new.target){
return new F();
}
}
console.log(F() instanceof F)
//true
console.log(new F() instanceof F)
//true
You shouldn't return anything in a constructor. A constructor is used to initialize the object. In case you want to know what happens is that if you return 5 then n will simply be an empty object and if you return for example { a: 5 }, then n will have a property a=5.
To answer your specific question:
function MyConstructor()
{
return 5;
}
var n = new MyConstructor();
n is an object instance of MyConstructor.
function SomeObject(name) {
this.name = name;
this.shout = function() {
alert("Hello " + this.name)
}
}
function MyConstructor()
{
return new SomeObject("coure06");
}
var n = new MyConstructor();
n.shout();
n is an instance of SomeObject (call n.shout() to prove it)
To make this all absolutely clear...
1) If you return a primitive type, like a number or a string, it will be ignored.
2) Otherwise, you will pass back the object
Functions and constructors are exactly the same in JavaScript, but how you call them changes their behaviour. A quick example of this is below...
function AddTwoNumbers(first, second) {
return first + second;
}
var functionCall = AddTwoNumbers(5, 3);
alert(functionCall);// 8
var constructorCall = new AddTwoNumbers(5, 3);
alert(constructorCall);// object

Understanding Prototypal Inheritance

var Object1 = {};
var Object2 = new Object();
var Object3 = Object.create({});
When i check whether the prototype is equal to Object.prototype:
The first two return true while the third one returns false.
Why is this happening?
Object.getPrototypeOf(Object1)===Object.prototype //true
Object.getPrototypeOf(Object2)===Object.prototype //true
Object.getPrototypeOf(Object3)===Object.prototype //false
Simply because if you take a look at the Object.create() in the documentation, you will that this method:
creates a new object with the specified prototype object and
properties.
And if you call it with :
Object.create({})
You are not passing a prototype but an empty object with no properties.
So as stated in comments you need to call it like this:
Object.create(Object.prototype)
The Object.create() method creates a new object with the specified prototype object and properties.
Behind the scenes it does the following:
Object.create = (function() {
var Temp = function() {};
return function (prototype) {
if (arguments.length > 1) {
throw Error('Second argument not supported');
}
if (typeof prototype != 'object') {
throw TypeError('Argument must be an object');
}
Temp.prototype = prototype;
var result = new Temp();
Temp.prototype = null;
return result;
};
})();
So the right use would be:
var Object3 = Object.create(Object.prototype);
Or if you want to make your example work:
Object.getPrototypeOf(Object.getPrototypeOf(Object3)) === Object.prototype // true
Here the prototype chain comes into play:
console.dir(Object3)
-> __proto__: Object (=== Your Object Literal)
-> __proto__: Object (=== Object.prototype)

Meaning of keyword "new" in javascript

I've read the topic about "new" keyword in javascript (What is the 'new' keyword in JavaScript?). But, i'm still in the fog; let's talk about this example :
var foo = function() {
return {
setA: function(a) {
this.a = a;
},
readA: function() {
console.log(this.a);
}
};
};
And now what's about these two pieces of code :
One:
var bob1 = foo();
bob1.setA(10);
bob1.readA();
Two:
var bob2 = new foo();
bob2.setA(10);
bob2.readA();
I cannot see any differences at my level. So what is the gain to use the keyword "new" ?
If your function returns object directly, then you do not need an new operator.
The new keys does more than that.
Lets say
function Animal(kind, name) {
this.kind = kind;
this.name = name;
}
Animal.prototype.walk = function() {
console.log('Walking');
}
Then you are doing
var animal = new Animal();
Javascript engine will do following things
var o = Object.create(Animal.prototype)
Animal.apply(o, arguments);
return o;
Object.create will do the prototype inheritance of the prototype object of Animal function. So animal object will have its own properties and its inherited property.
i'm still in the fog about new; let's talk about this example :
var foo = function() {
return {
setA: function(a) {
this.a = a;
},
readA: function() {
console.log(this.a);
}
};
};
We shouldn't talk about this example. Whether or not we use new with this function does not make a difference, because of the way new works:
A new object is created, inheriting from foo.prototype.
The constructor function foo is called with the specified arguments and this bound
to
the newly created object.
The object returned by the constructor function becomes the result
of the whole new expression. If the constructor function doesn't
explicitly return an object, the object created in step 1 is used
instead. (Normally constructors don't return a value, but they can
choose to do so if they want to override the normal object creation
process.)
Step 3 is the thing to look at here. You're creating and returning an object (the object literal), so that will become assigned to bob1. Usually, constructor functions do not return anything, and the new instance that is implicitly created in step1 (and available inside the function as this) becomes the result.
Both new foo() and foo() do only assign your object literal to the bob variable - no difference in the result. The instance created by the new is totally ignored by your code. It would be different in the following examples:
function foo() {
this.setA = function(a) {
this.a = a;
};
this.readA = function() {
console.log(this.a);
};
// return this; is implicit
}
var bob = new foo; // OK
var bob = foo(); // horrible error
If the constructor function foo returns an object, then new foo() is identical to calling the function foo() directly. We can prove this is so by examining the ECMAScript behavior for new:
Return the result of calling the [[Construct]] internal method on constructor [i.e., the constructor function]...
The [[Construct]] internal method of a function is a special wrapper for calling the function's [[Call]] internal method (which is just the function's normal behavior). Let's see the end of [[Construct]] to see how this wrapper behaves:
8) Let result be the result of calling the [[Call]] internal property of F [the function invoked by new], providing obj as the this value and providing the argument list passed into [[Construct]] as args.
9) If Type(result) is Object then return result.
10) Return obj.
In your case, your constructor function foo returns an object, so step 9 of [[Construct]] (and therefore, in turn, new foo()) returns that object. But we see in step 10 that [[Construct]] could return some other value called obj, which is equal to the this value inside the constructor. Let's rewind and see what that's all about:
1) Let obj be a newly created native ECMAScript object.
...
4) Let proto be the value of calling the [[Get]] internal property of F with argument "prototype".
5) If Type(proto) is Object, set the [[Prototype]] internal property of obj to proto.
Here we see the real power of new: if the constructor function does not return an object (and therefore the [[Construct]] operation launched by new is allowed to return obj), then prototypal inheritance takes place. The [[Prototype]] of obj (a.k.a. obj.__proto__) is set to the prototype property of the constructor method. This means that if foo doesn't return an object (and instead modifies this), and foo.prototype.someProp is set, then an instance returned from var instance = new foo() will have access to instance.someProp.
Thus, a different way to write your code might be:
var foo = function() { };
foo.prototype.setA = function(a) { this.a = a; };
foo.prototype.setA = function(a) { console.log(this.a); };
In this case, new foo() produces an object whose prototype chain includes foo.prototype, while foo() does not. This has the benefit of lower memory use: all foo instances here share common prototypal methods, instead of having each instance carry its own separate functions.

What values can a constructor return to avoid returning this?

What are the exact circumstances for which a return statement in Javascript can return a value other than this when a constructor is invoked using the new keyword?
Example:
function Foo () {
return something;
}
var foo = new Foo ();
If I'm not mistaken, if something is a non-function primitive, this will be returned. Otherwise something is returned. Is this correct?
In other words, what values can something take to cause (new Foo () instanceof Foo) === false?
The exact condition is described on the [[Construct]] internal property, which is used by the new operator:
From the ECMA-262 3rd. Edition Specification:
13.2.2 [[Construct]]
When the [[Construct]] property for a Function object F is
called, the following steps are taken:
Create a new native ECMAScript object.
Set the [[Class]] property of Result(1) to "Object".
Get the value of the prototype property of F.
If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3).
If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as
described in 15.2.3.1.
Invoke the [[Call]] property of F, providing Result(1) as the this value and
providing the argument list passed into [[Construct]] as the
argument values.
If Type(Result(6)) is
Object then return Result(6).
Return Result(1).
Look at steps 7 and 8, the new object will be returned only if the
type of Result(6) (the value returned from the F constructor
function) is not an Object.
Concrete examples
/*
ECMA 262 v 5
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
"4.3.2
primitive value
member of one of the types Undefined, Null, Boolean, Number, Symbol, or String as defined in clause 6"
*/
var Person = function(x){
return x;
};
console.log(Person.constructor);
console.log(Person.prototype.constructor);
console.log(typeof(Person));
console.log(typeof(Person.prototype));
function log(x){
console.log(x instanceof Person);
console.log(typeof x);
console.log(typeof x.prototype);
}
log(new Person(undefined));
log(new Person(null));
log(new Person(true));
log(new Person(2));
log(new Person(""));
//returns a function not an object
log(new Person(function(){}));
//implementation?
//log(new Person(Symbol('%')));
I couldn't find any documentation on the matter, but I think you're correct. For example, you can return new Number(5) from a constructor, but not the literal 5 (which is ignored and this is returned instead).
As a side note, the return value or this is just part of the equation.
For example, consider this:
function Two() { return new Number(2); }
var two = new Two;
two + 2; // 4
two.valueOf = function() { return 3; }
two + 2; // 5
two.valueOf = function() { return '2'; }
two + 2; // '22'
As you can see, .valueOf() is internally used and can be exploited for fun and profit. You can even create side effects, for example:
function AutoIncrementingNumber(start) {
var n = new Number, val = start || 0;
n.valueOf = function() { return val++; };
return n;
}
var auto = new AutoIncrementingNumber(42);
auto + 1; // 43
auto + 1; // 44
auto + 1; // 45
I can imagine this must have some sort of practical application. And it doesn't have to be explicitly a Number either, if you add .valueOf to any object it can behave as a number:
({valueOf: function() { return Math.random(); }}) + 1; // 1.6451723610516638
You can exploit this to make an object that always returns a new GUID, for instance.
Trying to put a few points in simpler words.
In javascript, when you use a new keyword on a function and if,
function does not return anything, it will return an intended object
function User() {
this.name = 'Virat'
}
var user = new User();
console.log(user.name); //=> 'Virat'
function returns any truthy complex object [object, array, function etc], that complex object takes priority and user variable will hold the returned complex object
function User() {
this.name = 'Virat';
return function(){};
}
var user = new User();
console.log(user.name); //=> undefined
console.log(user); //=> function
function returns any literal, constructor takes priority and it will return an intended object
function User() {
this.name = 'Virat';
return 10;
}
var user = new User();
console.log(user.name); //=> 'Virat'
When you are using the new keyword, an object is created. Then the function is called to initialise the object.
There is nothing that the function can do to prevent the object being created, as that is done before the function is called.

Categories

Resources