Node.js的模块导出exports 和 module.exports 的区别

关于exports和module.exports的关系可以总结为:

  1. module.exports 初始值为一个空对象 {},所以 exports 初始值也是 {}
  2. exports 是指向的 module.exports 的引用
  3. require() 返回的是 module.exports 而不是 exports

每一个Node.js执行文件,都自动创建一个module对象,同时,module对象会创建一个叫exports的属性,初始化的值是 {}

 module.exports = {};
 
 
  • 1
  • 1

exports和module.exports指向同一块内存,但require()返回的是module.exports而不是exports。

var str = "difference"
exports.a = str;
exports.b = function () {

}


 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

给 exports 赋值其实是给 module.exports 这个空对象添加了两个属性而已,上面的代码相当于:

var str = "difference"
module.exports.a = str;
module.exports.b = function () {

}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

先来看下exports和module.exports的使用

使用exports

app.js

var s = require("./log");
s.log("hello");
 
 
  • 1
  • 2
  • 1
  • 2

log.js


exports.log =function (str) {
    console.log(str);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

使用module.exports

app.js

var s = require("./log");
s.log("hello");
 
 
  • 1
  • 2
  • 1
  • 2

log.js

module.exports =function (str) {
    console.log(str);
}
 
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

上述两种用法都没问题,但如果这样使用

  exports = function (str) {
    console.log(str);
}
 
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

运行程序就会报错。

前面的例子中给 exports 添加属性,只是对 exports 指向的内存做了修改。而上例则是对exports指向的内存进行了覆盖,使exports指向了一块新的内存,这样,exports和module.exports指向的内存并不是同一块,exports和module.exports并无任何关系。exports指向的内存有了变化,而module.exports指向的内存并无变化,仍为空对象{}。

require得到的会是一个空对象,则会有

TypeError: s.log is not a function
 
 
  • 1
  • 1

报错信息。

再看下面的例子

app.js

 var x = require('./init');

 console.log(x.a)

 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

init.js

 module.exports = {a: 2}
 exports.a = 1 
 
 
  • 1
  • 2
  • 1
  • 2

运行app.js会有输出

2
 
 
  • 1
  • 1

这也就是module.exports对象不为空的时候exports对象就自动忽略,因为module.exports通过赋值方式已经和exports对象指向的变量不同了,exports对象怎么改和module.exports对象没关系了。

 exports = module.exports = somethings
 
 
  • 1
  • 1

等价于

  module.exports = somethings
  exports = module.exports
 
 
  • 1
  • 2
  • 1
  • 2

原因也很简单, module.exports = somethings 是对 module.exports 进行了覆盖,此时 module.exports 和 exports 的关系断裂,module.exports 指向了新的内存块,而 exports 还是指向原来的内存块,为了让 module.exports 和 exports 还是指向同一块内存或者说指向同一个 “对象”,所以我们就 exports = module.exports 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将 C++ 代码导出Node.js 模块,可以使用 Node.js 的 C++ Addons API。以下是简单的步骤: 1. 创建一个 C++ 文件,编写 C++ 代码。 2. 在 C++ 文件中包含 node.h 头文件,该文件包含 Node.js 的 C++ Addons API。 3. 编写和导出 Node.js 模块的函数。可以使用 NODE_MODULE 宏将其导出Node.js 模块。 例如,以下是将 C++ 函数 add 导出Node.js 模块的示例代码: ```c++ #include <node.h> namespace demo { using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; using v8::Object; using v8::String; using v8::Value; void Add(const FunctionCallbackInfo<Value>& args) { Isolate* isolate = args.GetIsolate(); // 检查参数个数 if (args.Length() < 2) { isolate->ThrowException( Exception::TypeError( String::NewFromUtf8(isolate, "Wrong number of arguments"))); return; } // 检查参数类型 if (!args[0]->IsNumber() || !args[1]->IsNumber()) { isolate->ThrowException( Exception::TypeError( String::NewFromUtf8(isolate, "Wrong arguments"))); return; } // 计算结果 double value = args[0]->NumberValue(isolate) + args[1]->NumberValue(isolate); Local<Number> num = Number::New(isolate, value); // 返回结果 args.GetReturnValue().Set(num); } void Initialize(Local<Object> exports) { NODE_SET_METHOD(exports, "add", Add); } NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize) } // namespace demo ``` 在上面的示例中,我们使用 NODE_MODULE 宏将 Initialize 函数导出Node.js 模块。其中,NODE_GYP_MODULE_NAME 是 Node.js 模块的名称,可以在 binding.gyp 中配置。 最后,使用以下命令将 C++ 代码编译为 Node.js 模块(假设 C++ 文件名为 addon.cc): ``` node-gyp configure build ``` 编译成功后,将生成一个名为 build/Release/addon.node 的文件,即为 Node.js 模块。在 Node.js 中使用 require 函数加载该模块即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值