JavaScript misfeature

Today a friend of mine checked in code that read:

    var stream = new fs.createReadStream(filename);

The ‘new’ in the code was not intended. Our expansive auto tests passed without a glitch. In fact, the ‘stream’ variable was correctly set to the stream – exactly like if the ‘new’ keyword was not present.

It turns out that in JavaScript constructor functions can return values. If a constructor function returns a value that is of Object type, the ‘new’ operator discards the object it created and returns that value instead. This misfeature is part of the spec in 13.2.2.

So, what happens above is that the ‘new’ operator creates a new object. It runs the fs.createReadStream() like a constructor on this new object. But since fs.createReadStream() returned a stream which is of type Object, it discards the new object it created and returns the stream.