tags:

views:

145

answers:

7

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

A: 

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.

Darin Dimitrov
yes technically i shld not return, but what if return?
coure06
see my comment http://www.gibdon.com/2008/08/javascript-constructor-return-value.html
Haim Evgi
If you return 5 you will get an empty object, and if you return an object then n will probably point to this object.
Darin Dimitrov
Nope, just tested on firefox, if i return 5 it gives me default object. and if i return some object it gives me that object.
coure06
i have updated question
coure06
There are actually many common OOP patterns in Javascript that do manually return an object in a constructor. Even Douglas Crockford is ok with it.
Triptych
A: 

You can't return anything from constructor!

When you create a new instance (a new object) of a class using the new keyword, a constructor for that class is called. Constructors are used to initialize the instance variables (fields) of an object. Constructors are similar to methods, but with some important differences.

  • Constructor name is class name. A constructors must have the same name as the class its in.
  • Default constructor. If you don't define a constructor for a class, a default parameterless constructor is automatically created by the compiler. The default constructor calls the default parent constructor (super()) and initializes all instance variables to default value (zero for numeric types, null for object references, and false for booleans).
  • Default constructor is created only if there are no constructors. If you define any constructor for your class, no default constructor is automatically created.
  • Differences between methods and constructors.
    • There is no return type given in a constructor signature (header). The value is this object itself so there is no need to indicate a return value.
    • There is no return statement in the body of the constructor.
    • The first line of a constructor must either be a call on another constructor in the same class (using this), or a call on the superclass constructor (using super). If the first line is neither of these, the compiler automatically inserts a call to the parameterless super class constructor.

These differences in syntax between a constructor and method are sometimes hard to see when looking at the source. It would have been better to have had a keyword to clearly mark constructors as some languages do.

  • this(...) - Calls another constructor in same class. Often a constructor with few parameters will call a constructor with more parameters, giving default values for the missing parameters. Use this to call other constructors in the same class.
  • super(...). Use super to call a constructor in a parent class. Calling the constructor for the superclass must be the first statement in the body of a constructor. If you are satisfied with the default constructor in the superclass, there is no need to make a call to it because it will be supplied automatically.

Example of explicit this constructor call

public class Point {
    int m_x;
    int m_y;

    //============ Constructor
    public Point(int x, int y) {
        m_x = x;
        m_y = y;
    }

    //============ Parameterless default constructor
    public Point() {
        this(0, 0);  // Calls other constructor.
    }
    . . .
}

super(...) - The superclass (parent) constructor

An object has the fields of its own class plus all fields of its parent class, grandparent class, all the way up to the root class Object. It's necessary to initialize all fields, therefore all constructors must be called! The Java compiler automatically inserts the necessary constructor calls in the process of constructor chaining, or you can do it explicitly.

The Java compiler inserts a call to the parent constructor (super) if you don't have a constructor call as the first statement of you constructor. The following is the equivalent of the constructor above.

// Constructor (same as in above example)
public Point(int x, int y) {
    super();  // Automatically done if you don't call constructor here.
    m_x = x;
    m_y = y;
}
sagar
Probably a good explanation, but this is a JavaScript question dude ;)
Matt
Too bad, a lot of work went into this answer :(
John K
A: 

By definition, the constructor returns an instance of the object. You don't call a constructor explicitly as in your example, rather it is called whenever you create a new instance of the object.

Ben Hughes
+2  A: 

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.
CMS
Could the downvoter *at least* leave a comment? This is a perfectly valid answer...
CMS
+1 for a valid answer - unless someone can tell me why they down-voted it.
Sohnee
+4  A: 

i found this great link :

http://www.gibdon.com/2008/08/javascript-constructor-return-value.html

Haim Evgi
+1 The article taught me what I would have never guessed about returning values from JavaScript constructors. Very interesting.
John K
so the answer is d, right?
coure06
yes, you right :)
Haim Evgi
+4  A: 

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 for the body of the function.

Once the function body is executed, Javascript will return:

ANY object if the function manually returns one:

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 this alerts 'VROOM'
Triptych
A: 

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
Sohnee