首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Node.js -将module.exports用作构造函数

Node.js -将module.exports用作构造函数
EN

Stack Overflow用户
提问于 2013-12-12 11:53:14
回答 5查看 135.1K关注 0票数 124

根据Node.js手册:

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

给出的示例如下:

代码语言:javascript
复制
// file: square.js
module.exports = function(width) {
  return {
    area: function() {
      return width * width;
    }
  };
}

并像这样使用:

代码语言:javascript
复制
var square = require('./square.js');
var mySquare = square(2);
console.log('The area of my square is ' + mySquare.area());

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

代码语言:javascript
复制
var Square = require('./square.js');
var mySquare = new Square(2);
console.log('The area of my square is ' + mySquare.area());
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-12-12 12:11:06

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

模块导出

可以使用提供的exports变量将属性附加到该变量。一旦在另一个模块中需要,这些赋值属性就变得可用。也可以将对象分配给module.exports属性。在这两种情况下,require()返回的都是对module.exports的值的引用。

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

代码语言:javascript
复制
var theModule = {
  exports: {}
};

(function(module, exports, require) {

  // Your module code goes here

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

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

构造函数需要

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

所以下面是非常好的代码,我个人鼓励你这样做:

代码语言:javascript
复制
// 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"

对非构造函数的要求

类似于非构造函数的函数也是如此:

代码语言:javascript
复制
// My Module
exports.someFunction = function someFunction(msg) {
  console.log(msg);
}

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

Stack Overflow用户

发布于 2013-12-12 12:16:24

在我看来,一些node.js示例是人为设计的。

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

代码语言:javascript
复制
// 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;

用法

代码语言:javascript
复制
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的人来说

代码语言:javascript
复制
class Square {
  constructor(width) {
    this.width = width;
  }
  area() {
    return Math.pow(this.width, 2);
  }
}

export default Square;

在ES6中使用它

代码语言:javascript
复制
import Square from "./square";
// ...

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

票数 136
EN

Stack Overflow用户

发布于 2013-12-12 11:57:29

这个问题实际上与require()的工作原理没有任何关系。基本上,无论您在模块中将module.exports设置为什么,require()调用都会返回它。

这相当于:

代码语言:javascript
复制
var square = function(width) {
  return {
    area: function() {
      return width * width;
    }
  };
}

在调用square时,不需要new关键字。您不是从square返回函数实例本身,而是在最后返回一个新对象。因此,您可以简单地直接调用此函数。

有关new的更复杂的争论,请查看以下内容:Is JavaScript's "new" keyword considered harmful?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20534702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档