一、HTML的多文件引用。
HTML的宿主环境中,多个js文件共用一个HTML宿主,此时他们的作用域是公用的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="01.js"></script> →var a = 100
<script src="02.js"></script> →alert(a)
</body>
</html>
此时页面是可以弹出100的,因为此时01.js文件中的a是全局变量也就是window的属性,所以02.js是可以使用window.a的,也就是100。
二、Node.js的多文件引用。
app.js
01.js
app.js中:
require("./01.js")
console.log("app.js文件")
01.js中:
console.log("01.js文件")
输入命令:node app.js
在Node.js中require()引用文件在引用的同时也在执行,所以就能通过打印两个文件的内容。
三、Node.js中的js文件作用域天生隔离。
app.js
01.js
01.js文件:
var a = 100;
app.js文件:
require("./01.js")
console.log(a)
输入命令:node app.js
错误信息内容是a没有被定义。
js文件在Node.js中作用域隔离,因为Node.js没有window对象。
此时我们想要文件之间能过互相通信,所以需要让文件自己暴露,或者保留一个进出口通道,用来传递信息。
四、exports 命令。
app.js
a.js
app.js文件内容:
var a = require("./a.js")
// 输入a文件的num参数
console.log(a.num)
a.js文件内容:
var num = 100;
// 向外暴露num参数
exports.num = num;
输入命令:node app.js
两点建议:
开辟通道出入口的时候必须是 exports.** = **,此时**必须是统一的,不能有差异化。
正确方式:
a.js文件:
var b = 100;
exports.b = b;
在app.js引入:
var a = require("./a.js");
console.log(a.b)
错误的方式:
a.js文件:
var b = 100;
exports.c = b;
第二个:建议在接收文件的时候,文件名是什么就用什么命名。
正确的:
var a = require("./a.js");
错误的:
var b = require("./a.js");
上面两个建议虽然错误写法不会报错,但是我们要求同学们要统一规范。
五、exports的命名空间。
看下面的目录结构:
a.js
app.js
a.js文件:
var num = 100;
// 向外暴露num参数
exports.num = num;
app.js文件:
var a = require("./a.js")
// 输入a文件的num参数
console.log(a.num)
你会发现,我们在输出a.js文件的num值的时候使用的是a.num,这个a就是exports返回的一个对象,这样做有什么好处呢?这种写法天生有自己的命名空间。
app.js
round.js
rectangle.js
round.js和rectangle.js都定义了area函数,但是由于我们都有自己的命名空间,所以互不相干扰。
round.js文件:
function area(r){
return 3.14 * r * r
}
exports.area = area;
rectangle.js文件:
function area(a,b){
return a * b;
}
exports.area = area;
app.js文件:
var round = require("./round");
var rectangle = require("./rectangle");
console.log(round.area(5));
console.log(rectangle.area(5,6));

我们的exports是可以开辟多个通道的。比如round.js文件:
function area(r){
return 3.14 * r * r
}
function perimeter(r) {
return 3.14 * 2 * r;
}
exports.area = area;
exports.perimeter = perimeter;
五、module.exports命名。
当一个js文件仅仅希望开辟唯一通道展现一个参数时,通常是构造函数,此时我们可以使用module.exports命名进行暴露。
app.js
People.js
People.js文件:
function People(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
People.prototype.sayHello = function(){
console.log("你好我是"+this.name+",我是一个"+this.sex+"生,我今年"+this.age+"岁了!")
}
module.exports = People;
app.js文件:
var People = require("./People.js");
var xiaoming = new People.People("小明",18,"男");
xiaoming.sayHello()
此时我们发现小明在new的时候并没有使用和exports类似的命名空间对象,是因为modue.exports默认返回的不是对象,而是结果。可以在控制台打印输出查看。
所以,总结:
1,如果文件要暴露多个参数,此时需要命名空间使用exports.**=**;
2,如果只有一个参数并且是构造函数时使用module.exports.**;
六、文件夹的使用。
app.js
result.js
round.js
rectangle.js
index.js
此时我们将round.js和rectangle.js放到了一个result文件夹内部,被index.js进行整合。我们index.js文件:
var rectangle = require("./rectangle");
var round = require("./round");
exports.round = round;
exports.rectangle = rectangle;
app.js文件:
var result = require("./result");
console.log(result.round.area(5));
console.log(result.rectangle.perimeter(4,5));
如果我们require()没有.js后缀,此时Node.js会认为我们在引入一个文件夹,并且执行文件夹内部根目录的index.js文件。index.js:
var result = require("./result");
等价于下面的
var result = require("./result/index.js");
需要注意的是不能省略./
七、node_module文件夹。
Node.js中,如果文件夹内部存放了node_module文件夹,此时内部的文件引入的时候就不用了写./了。
app.js
node_module
result
round.js
rectangle.js
index.js
我们的result文件夹的内容和第六部分保持一致,就是被一个node_module文件夹包裹了,此时我们引入的时候也发生了变化。
var result = require("result");
console.log(result.round.area(5));
console.log(result.rectangle.perimeter(4,5));
总结,如果我们使用require去引入文件,不加./是引入node_module文件夹内部的文件,否则就是本地其他文件。
| require内容 | 引用地址 |
| require("./result.js") | 同目录下的result.js |
| require("./result") | 同目录下的result文件夹内部的index.js |
| require("result") | node_module文件夹内部的result文件夹内部的index.js |
| require("result.js") | node_module文件夹内部的result.js |
