3

The core of my question is, what's the difference between

var fs = new require('fs');

and

var fs = require('fs');

Are there any effects or caveats if I were to use new for all modules everywhere?

While using Webstorm, I noticed that I can get intellisense working only if I use new require('fs'). Before I start using it consistently for a better development experience, I wanted to know a bit more about it.

qwertynl
  • 3,912
  • 1
  • 21
  • 43
Mendhak
  • 8,194
  • 5
  • 47
  • 64
  • 2
    possible duplicate of [How does require work with new operator in node.js?](http://stackoverflow.com/questions/17604497/how-does-require-work-with-new-operator-in-node-js) – talles Dec 26 '13 at 15:31
  • 3
    @talles I don't think this is quite a duplicate of that question: that question asks about how parentheses around a `require` call affect the `new` operator; this question asks about how the `new` operator affects a `require` call. Concretely, this question compares `require()` vs `new require()` while I think that question compares `new (require()) and `new require()`. – apsillers Dec 26 '13 at 15:57
  • Yep, I already saw the linked question but it's quite different from what I'm asking, @apsillers got the intent right – Mendhak Dec 26 '13 at 20:43

3 Answers3

7

First of all: Do not confuse new require("...") (which invokes require as a constructor) with new (require("...")) (which invokes the return value of the require call as a constructor). You are doing the first one.

require was not intended to be invoked as a constructor with new. That's not Node-idiomatic, and generally weird. You shouldn't do it, since it reduces the readbility of your code. A future reader might easily mistake it for new (require("...")) (i.e., calling new on a constructor that is being returned by require), since normal Node style does not use new with require.

Now, let's talk about actual side effects.

new causes a function to run its [[Construct]] internal method, which takes the following actions:

  • invoke the function with a this set to a newly-created object whose prototype is set to the function's prototype property

  • Return a result:

    • if the function returns an object, return the result of the function
    • if the function returns anything else, return the newly-created this object

The return value new require will be the same as require for all modules whose exports value is non-primitive (which is true of virtually any module; they typically export a plain object or a function, which is also a kind of object). In the rare case that your module does export a primitive, though, then new will deny you access to that value.

The only other possible difference between require(...) and new require(...) is that the new variant is supplied with a different this value. However, require appears to ignore its this value totally. (Note that Module.prototype.require -- a different function from normal require -- does use its this value, but that's only used when you require submodules from a module, using module.require(...).)

apsillers
  • 112,806
  • 17
  • 235
  • 239
  • Good explanation with specific links. I also understand why you called it weird, I'll not pollute my code with `new require()` now! – Mendhak Dec 26 '13 at 20:46
1

The 'new' operator in Node.js is used to create a new instance of something. As you might know in Node.js functions themselves are first class objects. You can create new instance of a function by using 'new' operator that will reside inside a variable.

This is used in order to create many functions with the same body but different name so that they have their variables with different values in a program.

Require, on the other hand, is used to import a module that you have created elsewhere or an existing node modules like you might do by importing libs in other languages. Require in this case returns to the assigned variable the module that you are importing in your application.

When you use 'new' with require, it doesn't do anything but imports a new instance of the module that you are importing. This method is not needed, but it will work.

It is suggested to use new only when you want to create several instances of same object and/or want to clear up the older instance by creating newer instance of another object into the same variable.

Chetan Bhasin
  • 3,503
  • 1
  • 23
  • 36
-1

Think about it.

require returns something.

It is the same as doing:

var foo = function(bar) {
    this.bar = bar;
};

var f = foo('bar');
console.log(f.bar); //ERROR
//vs:
var y = new foo('bar');
console.log(y.bar); // 'bar'

So all your code does is invoke new with the return from require

qwertynl
  • 3,912
  • 1
  • 21
  • 43
  • 5
    Unless I misunderstand you final setence (which I might), this is not correct. `new (require('fs'))` would do what you describe ("*invoke `new` with the return from `require`*"). `new require('fs')` is closer to `require.call(Object.create(require.prototype), 'fs')`. – apsillers Dec 26 '13 at 15:43