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

根据 Node.js 手册:

如果希望模块导出的根是一个函数(如 一个构造函数) ,或者如果你想导出一个完整的对象 赋值,而不是一次构建一个属性,将其赋值给 出口而不是出口。

给出的例子是:

// 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());
141944 次浏览

This question doesn't really have anything to do with how require() works. Basically, whatever you set module.exports to in your module will be returned from the require() call for it.

这相当于:

var square = function(width) {
return {
area: function() {
return width * width;
}
};
}

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

关于 new的更复杂的参数,请查看以下内容: JavaScript 的“新”关键字被认为是有害的吗?

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

模组输出

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

一个关于如何定义模块的伪代码示例:

var theModule = {
exports: {}
};


(function(module, exports, require) {


// Your module code goes here


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

在上面的例子中,module.exportsexports是同一个对象。最酷的部分是,你在 CommonJS 模块中看不到任何这样的东西,因为整个系统都在处理这个问题,你只需要知道有一个具有导出属性的模块对象和一个导出变量,它指向 module.export 所做的相同的事情。

需要与构造函数

因为你可以直接将一个函数附加到 module.exports,所以实际上你可以返回一个函数,就像任何函数一样,它可以被管理为 构造函数(这是斜体的,因为在 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"

对非构造函数的要求

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"

在我看来,有些 node.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;

Usage

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关键字来初始化它,其他的一切都保持不变。

The example code is:

总体来说

square(width,function (data)
{
console.log(data.squareVal);
});

使用以下方法可能有效

exports.square = function(width,callback)
{
var aa = new Object();
callback(aa.squareVal = width * width);
}

最后,Node 是关于 Javascript 的。JS 有几种方法来完成一些事情,得到一个“构造函数”是一回事,重要的是返回一个函数

这种方式实际上是创建一个新函数,例如我们使用 JS on Web Browser 环境创建的函数。

个人而言,我更喜欢原型方法,正如 Sukima 在这篇文章中所建议的: Js-使用 module.export 作为构造函数