http://nqdeng.github.io/7-days-nodejs/#1.1
http://nodejs.cn/ (中文官网)
https://nodejs.org/en/ (英文官网)
计时开始:2019-5-28 15:38:54
一、 什么是NodeJS
- JS 是脚本语言,脚本语言运行需要一个解析器。NodeJS 就是一个解析器。
- 解析器就是一个运行环境。可以定义数据结构,进行运算,提供内置对象和方法。
写在HTML页面里的JS,浏览器充当了解析器的角色。运行在浏览器中的JS的用途是操作DOM,浏览器就提供了document之类的内置对象。
运行在NodeJS中的JS的用途是操作磁盘文件或搭建HTTP服务器,NodeJS就相应提供了fs、http等内置对象。
二、 NodeJS的 Modules(模块)
- 在 Node.js 模块系统中,每个文件都被视为一个独立的模块。
- require 函数用于在当前模块中加载和使用其他的模块。
- 传入一个模块名,返回一个模块导出对象。模块名中的.js扩展名可以省略。
const foo= require(./foo.js)
(模块名中的.js 扩展名可以省略掉)var data = require('./data.json')
(也可以加载json 文件)
- exports 用于导出模块公有方法或属性。
exports.hello = function() {mconsole.log('Hello World!')}
- module.exports 用于导出一个对象(类似class, 包含很多属性或方法)。
- 主模块作为程序入口点,所有模块在执行过程中只初始化一次。
- 模块在第一次加载后会被缓存。(caching)
- 多次调用 同一个模块不会导致模块的代码被执行多次。
- 如果想要多次执行同一个模块,可以导出一个函数,然后调用该函数。
- require() 总是会优先加载核心模块。核心模块定义在 Node.js 源代码的 /lib 目录下。(core modules)
- 当循环调用 require() 时,一个模块可能在未完成执行时被返回。(cycles)
- 当没有以 '/'、 './' 或 '../' 开头来表示文件时,这个模块必须是一个核心模块或加载自 node_modules 目录,例如 require('fs')。
- folders as modules ,即把程序和库放到一个单独的文件夹, 再在这个文件夹的根目录创建一个package.json 文件,并指定 main 入口文件。
// package.json 内容如下:
{
"name": "some-library",
"main": "./lib/some-library.js",
}
- 如果当前所在目录是 ./some-library , 则 require(./some-library) 会尝试加载 ./some-library/lib/some-library.js
- 如果目录里没有 package.json 文件,则 Node.js 就会试图加载目录下的 index.js 或 index.node 文件,即./some-library/index.js 或./some-library/index.node。
1. Example: require and exports
// 文件 foo.js:
const circle = require('./circle.js'); // loads the module circle.js in the same directory as foo.js
console.log(`The area of a radius 4 is ${circle.area(4)}`) ;
// 文件 circle.js
const { PI } =Math;
exports.area = (r) => PI*r **2;
2. Example: module.exports
// 文件 bar.js:
const Square =require(./square.js); // loads the module square.js
const mySquare = new Square(4); // new a Square class
console.log(`The area of mySquare is ${mySquare.area()}`); // execute its method of the Square class
// 文件 square.js
module.exports = class Square {
constructor(width) {
this.width = width;
}
area() {
return this.width**2;
}
};
----------------------------------------------------
e.g. 2
// hello.js
function Hello() {
var name;
this.setName = function(thyName) {
name = thyName;
};
this.sayHello = function() {
console.log('Hello ' + name);
};
};
module.exports = Hello;
// main.js
var Hello=require(./hello.js)
hello = new Hello();
hello.setName('WWW');
hello.sayHello();
3. Example:module 被循环调用
// a.js:
console.log('a starting');
exports.done = false;
const b = require('./b.js');
console.log('in a, b.done = %j', b.done);
exports.done = true;
console.log('a done');
// b.js:
console.log('b starting');
exports.done = false;
const a = require('./a.js');
console.log('in b, a.done = %j', a.done);
exports.done = true;
console.log('b done');
// main.js:
console.log('main starting');
const a = require('./a.js');
const b = require('./b.js');
console.log('in main, a.done = %j, b.done = %j', a.done, b.done);
// 执行过程:
当 main.js 加载 a.js 时, a.js 又加载 b.js。
此时, b.js 会尝试去加载 a.js。 为了防止无限的循环,会返回一个 a.js 的 exports 对象的 未完成的副本 给 b.js 模块。
然后 b.js 完成加载,并将 exports 对象提供给 a.js 模块。
> main.js
main starting
const a = require('./a.js'); //去加载a.js
>> a.js
a starting
exports.done = false;
const b = require('./b.js'); //去加载b.js
>>> b.js
b starting
exports.done = false;
const a = require('./a.js') // 返回一个 a.js 的 exports 对象的未完成的副本给b.js exports.done = false;
in b, a.done = false
exports.done = true;
b done // b.js 完成加载
>> a.js // 继续a.js 的加载
const b = require('./b.js'); // 加载已经完成的 b.js
in a, b.done = true
exports.done = true;
a done
> main.js
const b = require('./b.js'); //完成 a.js b.js 的加载
in main, a.done = true, b.done = true
转载于:https://www.jianshu.com/p/c85668914293