What is returned from a constructor?

Viewed 41894

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

7 Answers

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

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.)

Related