Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
513 views
in Technique[技术] by (71.8m points)

javascript - Node.js - use of module.exports as a constructor

According to the Node.js manual:

If you want the root of your module's export to be a function (such as a constructor) or if you want to export a complete object in one assignment instead of building it one property at a time, assign it to module.exports instead of exports.

The example given is:

// file: square.js
module.exports = function(width) {
  return {
    area: function() {
      return width * width;
    }
  };
}

and used like this:

var square = require('./square.js');
var mySquare = square(2);
console.log('The area of my square is ' + mySquare.area());

My question: why does the example not use square as an object? Is the following valid and does it make the example more "object oriented"?

var Square = require('./square.js');
var mySquare = new Square(2);
console.log('The area of my square is ' + mySquare.area());
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

CommonJS modules allow two ways to define exported properties. In either case you are returning an Object/Function. Because functions are first class citizens in JavaScript they to can act just like Objects (technically they are Objects). That said your question about using the new keywords has a simple answer: Yes. I'll illustrate...

Module exports

You can either use the exports variable provided to attach properties to it. Once required in another module those assign properties become available. Or you can assign an object to the module.exports property. In either case what is returned by require() is a reference to the value of module.exports.

A pseudo-code example of how a module is defined:

var theModule = {
  exports: {}
};

(function(module, exports, require) {

  // Your module code goes here

})(theModule, theModule.exports, theRequireFunction);

In the example above module.exports and exports are the same object. The cool part is that you don't see any of that in your CommonJS modules as the whole system takes care of that for you all you need to know is there is a module object with an exports property and an exports variable that points to the same thing the module.exports does.

Require with constructors

Since you can attach a function directly to module.exports you can essentially return a function and like any function it could be managed as a constructor (That's in italics since the only difference between a function and a constructor in JavaScript is how you intend to use it. Technically there is no difference.)

So the following is perfectly good code and I personally encourage it:

// My module
function MyObject(bar) {
  this.bar = bar;
}

MyObject.prototype.foo = function foo() {
  console.log(this.bar);
};

module.exports = MyObject;

// In another module:
var MyObjectOrSomeCleverName = require("./my_object.js");
var my_obj_instance = new MyObjectOrSomeCleverName("foobar");
my_obj_instance.foo(); // => "foobar"

Require for non-constructors

Same thing goes for non-constructor like functions:

// My Module
exports.someFunction = function someFunction(msg) {
  console.log(msg);
}

// In another module
var MyModule = require("./my_module.js");
MyModule.someFunction("foobar"); // => "foobar"

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...