Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this constructor not return a string? [duplicate]

Tags:

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

like image 928
coure2011 Avatar asked Jul 28 '10 05:07

coure2011


People also ask

Why do constructors not return values?

So the reason the constructor doesn't return a value is because it's not called directly by your code, it's called by the memory allocation and object initialization code in the runtime. Its return value (if it actually has one when compiled down to machine code) is opaque to the user - therefore, you can't specify it.

Why constructors do not have any return type with example?

Constructor looks like method but it is not. It does not have a return type and its name is same as the class name. Mostly it is used to instantiate the instance variables of a class. If the programmer doesn't write a constructor the compiler writes a constructors on his behalf.

Which type of constructor does not have return type?

A constructor cannot have a return type (not even a void return type). A common source of this error is a missing semicolon between the end of a class definition and the first constructor implementation. The compiler sees the class as a definition of the return type for the constructor function, and generates C2533.

Can we write duplicate constructor?

Yes, a copy constructor can be made private.


7 Answers

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'
like image 158
Kenan Banks Avatar answered Oct 02 '22 03:10

Kenan Banks


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:

  1. Let obj be a newly created native ECMAScript object.
  2. Set all the internal methods of obj as specified in 8.12.
  3. Set the [[Class]] internal property of obj to "Object".
  4. Set the [[Extensible]] internal property of obj to true.
  5. Let proto be the value of calling the [[Get]] internal property of F with argument "prototype".
  6. If Type(proto) is Object, set the[[Prototype]]` internal property of obj to proto.
  7. 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.
  8. 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.
  9. If Type(result) is Object then return result.
  10. Return obj.
like image 20
Christian C. Salvadó Avatar answered Oct 02 '22 02:10

Christian C. Salvadó


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');
like image 27
Haim Evgi Avatar answered Oct 02 '22 01:10

Haim Evgi


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
like image 41
Marinos An Avatar answered Oct 02 '22 03:10

Marinos An


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.

like image 36
Darin Dimitrov Avatar answered Oct 02 '22 01:10

Darin Dimitrov


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
like image 33
Fenton Avatar answered Oct 02 '22 01:10

Fenton


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

like image 44
Philipp Munin Avatar answered Oct 02 '22 01:10

Philipp Munin