node——12-模块系统、其他成员

模块导出——仅对象

main.js

var fooExports = require('./foo');

// ReferenceError: foo is not defined
// console.log(foo);

// 这种方式导出的都是对象
// { add: [Function: add], foo: 'bar', str: 'hello world' }
console.log(fooExports);

foo.js

var foo = 'bar';

function add(x, y) {
    return x + y;
}

// 只能得到我想要给你的成员
// 这样做的目的是为了解决变量命名冲突的问题
exports.add = add;

// exports 是一个对象
// 我们可以通过多次为这个对象添加成员实现
exports.foo = foo;
exports.str = 'hello world';

模块导出——其他类型

现在,我有另一个需求:
希望加载得到直接就是一个:

  • 方法
  • 字符串
  • 数字
  • 数组

main.js

var fooExports = require('./foo');

console.log(fooExports);

foo.js

function add(x, y) {
    return x + y;
}

// exports = add;//没用

// 如果某个模块需要直接导出某个成员,而非挂载的方式
// 那这个时候必须使用下面的方式
// module.exports = add;// [Function: add]
module.exports = 'hello';// hello

// 注意:重复写会后面的覆盖前面的(hello 被覆盖掉了)
module.exports = function (x, y) {
    return x + y;
};// [Function]

// 通过对象的方式导出多个成员
module.exports = {
    a: function (x, y) {
        return x + y;
    },
    b: 'hello',
};// { a: [Function: a], b: 'hello' }

模块系统原理

在 Node 中,每个模块内部都有一个自己的 module 对象,该对象中有个成员 exports 也是对象

// 类似于这个
var module = {
    exports: {
        foo: 'bar'
    }
};

如果你需要对外导出成员,只需要把导出的成员挂载到 module 对象上去

// module.exports.foo = 'bar';

// module.exports.add = function (x, y) {
//     return x + y;
// };

// 上面那种方法点的太多了,所有 node.js 提供了 exports === module.exports
console.log((exports === module.exports));// true

// 所以可以简化为
exports.foo = 'bar';

exports.add = function (x, y) {
    return x + y;
};

require 时就相当于默认在代码最后添加一句:return module.exports

// 另一个 js 文件获取
var fooExports = require('./foo');

console.log(fooExports);// { foo: 'bar', add: [Function] }

所以想要导出其他类型的数据

// 相当于把 exports 对象类型重新定义了
module.exports = 'hello';

而实际用的时候:

  • 导出多个成员:exports.xxx = xxx
  • 导出多个成员也可以:module.exports = { a:xxx, b:xxx }
  • 导出单个成员:module.exports = 'hello'

注意:如果实在分不清 exports 和 module.exports,那就选择忘记 exports,而只使用 module.exports 也没问题

导出文件路径及路径名

foo.js 中

console.log(__filename);
console.log(__dirname);

main.js 中引用 foo.js 就会打印出来:
在这里插入图片描述

exports 和 module.exports 的区别

每个模块中都有一个 module 对象
module 对象中有一个 exports 对象
我们可以把需要导出的成员都挂载到 module.exports 接口对象中
也就是:moudle.exports.xxx = xxx 的方式
但是每次都 moudle.exports.xxx = xxx 很麻烦,点儿的太多了
所以 Node 为了你方便,同时在每一个模块中都提供了一个成员叫:exports
exports === module.exports 结果为 true
所以对于:moudle.exports.xxx = xxx 的方式 完全可以:expots.xxx = xxx
当一个模块需要导出单个成员的时候,这个时候必须使用:module.exports = xxx 的方式
不要使用 exports = xxx 不管用
因为每个模块最终向外 return 的是 module.exports
exports 只是 module.exports 的一个引用
所以即便你为 exports = xx 重新赋值,也不会影响 module.exports
但是有一种赋值方式比较特殊:exports = module.exports 这个用来重新建立引用关系的

node 中的其他成员

在每个模块中,除了 requireexports 等模块相关的 API 之外,还有两个特殊的成员:

  • __dirname 可以用来 动态获取 当前文件模块所属目录的绝对路径
  • __filename 可以用来 动态获取 当前文件的绝对路径(包含当前文件的文件名)

出现目的:解决 node 中 ./a.txt 读取文件只是相对于执行 node 命令所处的路径

  • fun.js
  • code
    • index.js
    • a.txt

如果通过 fun.js 调用 index.js 读取文件 a.txt,执行顺序为 fun.js >> index.js >> a.txt,那么 node 调用 fun.js ,执行到 index.js 便会出错,因为 a.txt 的读取会在 fun.js 去寻找

所以为了解决这个问题,把相对路径转换为绝对路径,在 index.js 中,便可以用 __dirname + '/a.txt' 代替 ./a.txt ,为了避免手动拼接带来的一些低级错误,推荐用 path 模块的 path.join(__dirname,'./a.txt')

注意:模块中的路径标识 require 不受影响(文件的读取 fs.readFile() 会出现上面错误)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值