views:

187

answers:

4

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?

IOW, what values can something take to cause (new Foo () instanceof Foo) === false?

A: 

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.

Guffa
I'm not taking about that. I know you can do what I claim (I've tried it), but I don't know the definitive cases for which it occurs. In my example, it IS possible to end up with `(foo instanceof Foo) === false`.
trinithis
@trin - short answer no
JonH
A: 

The new keyword creates an object, and then calls the function. You are correct in that you can return anything you want. As a matter of fact, it is a good way to implement public and private members. Here is an example:

function Foo() {
    var privateVariable1 = 'Hello';
    var privateVariable2 = 'World';

    function privateMethod() {
        //do stuff
    }

    return {
        publicVariable1 : null,
        publicVariable2 : 'bar',

        getString : function() {
            return privateVariable1 + ' ' + privateVariable2;
        }
    };
}
Gabriel McAdams
If you replace the return statment with `return 1;`, the returned value is not `1`. The returned value is `this`. Thus you cannot return 'anything'.
trinithis
any object you want, I should say.
Gabriel McAdams
Please remember to accept this answer if you found it helpful.
Gabriel McAdams
+1  A: 

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

mkrause
+6  A: 

The exact condition is described on the [[Construct]] internal property, which is used by the new operator:

From the ECMA-262 3rd. Ediion Specification:

13.2.2 [[Construct]]

When the [[Construct]] property for a Function object F is called, the following steps are taken:

  1. Create a new native ECMAScript object.
  2. Set the [[Class]] property of Result(1) to "Object".
  3. Get the value of the prototype property of F.
  4. If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3).
  5. 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.
  6. 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.
  7. If Type(Result(6)) is Object then return Result(6).
  8. Return Result(1).

Look at the steps 7 and 8, the new object will returned only if the type of Result(6) (the value returned from the F constructor function) is not an Object.

CMS