3

Is it possible to write a javascript function that follows this (valid) typescript interface:

interface Foo{
    // constructor: 
    new (): string; 
}

i.e. Something that when called with a new operator returns a string. e.g. the following will not work.

function foo(){
    return "something";
} 
var x = new foo(); 
// x is now foo (and not string) whether you like it or not :) 
basarat
  • 261,912
  • 58
  • 460
  • 511
  • 1
    [ECMAScript 5, Sect. 13.2.2](http://www.ecma-international.org/ecma-262/5.1/#sec-13.2.2) has this to say about the return value of a constructor that constructs an object `obj` and returns `result`: "*If `Type(result)` is `Object` then return `result`. [Otherwise,] return `obj`.*" Thus, non-object return values cannot be returned from a constructor. – apsillers Jul 22 '13 at 13:06
  • @apsillers Thanks +1 the comment, If you post as answer I will plus 1 that as well (for the ecma spec link + quote). But for marking as answer rob answered first :) – basarat Jul 22 '13 at 13:13

2 Answers2

5

You should be able to do:

function foo(){
    return new String("something");
} 
var x = new foo(); 

console.log(x);

You can return any object, but literals don't work. See here: What values can a constructor return to avoid returning this?

Community
  • 1
  • 1
RobH
  • 3,604
  • 1
  • 23
  • 46
  • Awesome +1. It works. Now I am curious why `new String("string")` works but "string" does not? – basarat Jul 22 '13 at 13:03
  • 1
    Because string is a primitive, and String is an object type that represents string. The real question is "Why would you want to do this in the first place?" Using the new operator is intended to create instances of the function's return object. Why would you need many instances of your string value? – Joel Cochran Jul 23 '13 at 13:41
  • @JoelCochran Yes I know: `typeof "string" == 'string'` not object. http://jsfiddle.net/3mbeQ/ – RobH Jul 23 '13 at 13:49
  • Sorry @RobH: my response was to BASarat's question in the preceding comment. – Joel Cochran Jul 23 '13 at 17:55
2

ECMAScript 5's Section 13.2.2 (on the [[Construct]] internal property) has this to say about the return value of a constructor:

1) Let obj be a newly created native ECMAScript object.

...

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.

Thus, the return value of a constructor can only be an object. A string primitive like "foo" has a Type result of String rather than Object. This means that step 9 is false, so step 10 returns the constructed object, instead of the return value of the constructor function.

Instead, you must return an object (new String("foo")), as detailed in RobH's answer.

apsillers
  • 112,806
  • 17
  • 235
  • 239
  • as promised +1. Thanks for your time. Love the glider logo btw :) – basarat Jul 22 '13 at 13:17
  • @BASarat Thanks :) I think RobH is the right answer to accept here; I just wanted to address your "*why `new String("string")` works but `"string"` does not?*" question with the appropriate spec reference. – apsillers Jul 22 '13 at 14:24