0

When I write

function abc() {
 return 3;
}

var t = new abc();
console.log(t); // abc {}

However when i do this

function a() {
  this.name = 'test';
}

function b() {
  this.age = 33;
  return new a();
}

var p = new b();
console.log(p); // a { name = 'test'}

So In first example, why does it return an object when return is actually returning a number. And when i do return new Func() .... i get the new Obj.. the returned value.

In one scenario i get returned value, in other the main obj.

Muhammad Umer
  • 17,263
  • 19
  • 97
  • 168
  • Possible duplicate of [What is the 'new' keyword in JavaScript?](http://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript) – dnozay Oct 13 '15 at 00:55
  • since that's behavior of `new` we are discussing, I find it's related. we don't need to agree on that. – dnozay Oct 13 '15 at 01:14

2 Answers2

1

That's as per ES5.1 specification 13.2.2 [[Construct]]

Relevant part:

  1. 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.
  2. If Type(result) is Object then return result.
  3. Return obj.

The similar part from the ES2015: 9.2.2 [[Construct]] ( argumentsList, newTarget)

  1. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
  2. Remove from the execution context stack and restore callerContext as the running execution context.
  3. If result.[[type]] is return, then
    • If Type(result.[[value]]) is Object, return NormalCompletion(result.[[value]]).
    • If kind is "base", return NormalCompletion(thisArgument).
    • If result.[[value]] is not undefined, throw a TypeError exception.

Thanks to @Barmar for the summary:

In other words, if the constructor returns an object, new returns that object, otherwise it returns this

Community
  • 1
  • 1
zerkms
  • 249,484
  • 69
  • 436
  • 539
  • 3
    In other words, if the constructor returns an object, `new` returns that object, otherwise it returns `this`. – Barmar Oct 13 '15 at 00:49
1

This constructor is okay:

function foo() {
  // will set attribute on new object
  this.age = 33;
}
t = new foo;
Object.getPrototypeOf(t);  // foo

This one as well:

function bar() {
  // delegates construction to other method
  // object will not have prototype bar, but prototype baz
  return new baz();
}
t = new bar;
Object.getPrototypeOf(t);  // baz

But this constructor will not do what most people expect:

function b() {
  this.age = 33;
  // because you are returning a different object;
  // that other object will not have its .age attribute set
  // by the statements above.
  // object will not have prototype b, but prototype a
  return new a();
}
t = new b;
Object.getPrototypeOf(t);  // a

You could however do the following:

function b() {
  var o = new a();
  o.age = 33;
  // object will not have prototype b, but prototype a
  return o;
}
t = new b;
Object.getPrototypeOf(t);  // a
dnozay
  • 23,846
  • 6
  • 82
  • 104