Node.js - 使用 module.export 作为构造函数

2022-08-30 04:49:42

根据Node.js手册:

如果希望模块导出的根是一个函数(如构造函数),或者如果要在一个赋值中导出一个完整的对象,而不是一次生成一个属性,请将其分配给 module.export 而不是 export。

给出的示例是:

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

并像这样使用:

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

我的问题是:为什么这个例子不使用正方形作为对象?以下内容是否有效,它是否使示例更加“面向对象”?

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

答案 1

CommonJS 模块允许两种方法来定义导出的属性。在任一情况下,您都将返回对象/函数。因为函数在JavaScript中是一等公民,所以它们可以像对象一样行动(从技术上讲,它们是对象)。也就是说,您关于使用关键字的问题有一个简单的答案:是的。我将说明...new

模块导出

您可以使用提供的变量将属性附加到它。一旦在另一个模块中需要,这些分配的属性就变得可用。或者,可以将对象分配给 module.export 属性。在任一情况下,返回的 都是对 的值的引用。exportsrequire()module.exports

如何定义模块的伪代码示例:

var theModule = {
  exports: {}
};

(function(module, exports, require) {

  // Your module code goes here

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

在上面的示例中,是同一个对象。很酷的部分是,你不会在你的 CommonJS 模块中看到任何这些,因为整个系统都会为你处理所有你需要知道的是,有一个模块对象具有 export 属性和一个 export 变量,它指向 module.exports 所做的相同事情。module.exportsexports

要求与构造函数

由于您可以直接将函数附加到您,因此基本上可以返回一个函数,并且像任何函数一样,它可以作为构造函数进行管理(这是斜体,因为JavaScript中函数和构造函数之间的唯一区别是您打算如何使用它。从技术上讲,没有区别。module.exports

所以下面这些代码是非常好的,我个人鼓励它:

// 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"

非构造函数的要求

同样的事情也适用于非构造函数,如函数:

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

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

答案 2

在我看来,一些节点.js的例子是相当人为的。

你可能期望在现实世界中看到更多这样的东西

// square.js
function Square(width) {

  if (!(this instanceof Square)) {
    return new Square(width);
  }

  this.width = width;
};

Square.prototype.area = function area() {
  return Math.pow(this.width, 2);
};

module.exports = Square;

用法

var Square = require("./square");

// you can use `new` keyword
var s = new Square(5);
s.area(); // 25

// or you can skip it!
var s2 = Square(10);
s2.area(); // 100

对于ES6人

class Square {
  constructor(width) {
    this.width = width;
  }
  area() {
    return Math.pow(this.width, 2);
  }
}

export default Square;

在 ES6 中使用它

import Square from "./square";
// ...

使用类时,必须使用关键字来初始化它。其他一切都保持不变。new