2

This is a newbie query. I went through few similar posts, but they are not helping me enough. This post has 2 queries, but am putting together because their root seems the same.

I came across the following code snippet :

var Server = module.exports.Server = function Server(listener) {
  if (!(this instanceof Server)) return new Server(listener);
  //other code
}

module.exports.createServer = function(listener) {
  return new Server(listener);
};

I am unable to understand the use of if (!(this instanceof Server)) ; when can this not point to Server here ?

I tried putting a quick test for this :

var createTest = function(){
    console.log(this.toString());
    return new Test();
};

var Test = function Test(){
    console.log(this instanceof Test);
    console.log(this.toString());
    if (!(this instanceof Test)) 
    {
        return new Test();
    }
}

var tester = createTest();

which outputs :

[object global]
true
[object Object]

which further confuses me over why this.toString prints [object Object] - shouldn't it be [object Test] ?

Thanks !

1
  • I'm not sure, but perhaps it's because you're in the constructor, and therefore the class is not yet considered a Test object? Just a guess. Commented Oct 10, 2012 at 4:19

2 Answers 2

5

That's an idiom used to make new optional. For example:

function TraditionalTest() {
}
function IdiomaticTest() {
    if(!(this instanceof IdiomaticTest)) return new IdiomaticTest();
}

console.log(new TraditionalTest());  // [object Object]
console.log(TraditionalTest());      // undefined
console.log(new IdiomaticTest());    // [object Object]
console.log(IdiomaticTest());        // [object Object]

As for why it's [object Object] rather than [object Test], I don't know why it's defined that way, but that's the way it's defined:

When the toString method is called, the following steps are taken:

  1. If the this value is undefined, return "[object Undefined]".
  2. If the this value is null, return "[object Null]".
  3. Let O be the result of calling ToObject passing the this value as the argument.
  4. Let class be the value of the [[Class]] internal property of O.
  5. Return the String value that is the result of concatenating the three Strings "[object", class, and "]".

[[Class]] is referenced several times in the specification, but it only ever represents built-in types:

  • Arguments
  • Array
  • Boolean
  • Date
  • Error
  • Function
  • JSON
  • Math
  • Number
  • Object
  • RegExp
  • String
Sign up to request clarification or add additional context in comments.

2 Comments

Can you please explain the second part of my query too ?
+1 Where ES5 uses a word in [[]] (like [[Prototype]]) it means it's a specification mechanism. Implementations must behave as if they support it, but don't actually have to have it. So [[Class]] is just a way to define classes of objects without specifying that they actually have an internal, inaccessible Class attribute. They just have to behave as if they do. See ES5 §8.6.2 Object Internal Properties and Methods
1

That test makes sure that a new server instanced is created for both of these uses:

new module.exports.Server()

and for:

module.exports.Server()

In the second one, the this pointer would be the global object and thus would not be an instanceof Test. In that case, the code realizes that the constructor function was just called directly without new so no new object was created. Since that is not the intended use of the constructor, it forces a new to be used by invoking one and returning the result.

2 Comments

For the second part, how is console.log(this instanceof Test); returning true then ?
You are invoking it with return new Test(); which creates a new Test object and then calls the constructor with this set to that new object. So console.log(this instanceof Test); inside the constructor shows that this is indeed happening.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.