1、node环境
node执行环境REPL在命令行界面输入node进行REPL环境
常用的命令: .break--打断 .clear--清除 .exit--退出 .help--帮助文件 .save--保存界面上的命令到指定的文件 .load --把指定的js文件加载到命令行中 .editor--进入编辑器模式
node中设置环境变量用set 属性=值 查看某环境变量的值用 echo %属性名% 在mac环境下用的是 $属性名$
可以在以上地方查看所有的node环境变量, 注意:如果单从环境中读取是获取不到对应的值, 需要先设置,然后再读取
查看所有的环境变量,则可以在cmd模式下输入set回车便可看到所有的变量列表
__dirname:表示当前文件所在的文件夹地址
__filename:表示当前文件的全地址
node.js中的全局对象是global,相当于页面里的window对象
2、宏任务与微任务
js程序在走代码的时候,
会把代码分为同步和异步的,同步代码会进入程序的主线程,而异步代码会进入event loop中
当主线程的代码执行完成后,才会去执行异步的代码,
而异步的代码有分成setTimeout,setInterval以及其他的如读取文件,ajax请求两种类型
而前者(setTimeout与setInterval称之为Timer阶段)的优先级相对高而进入上图的循环之中,当执行到LoopActive的时候,会去再检测代码中是否存在异步,从而再走timer这个循环
console.log(1) setTimeout(() => console.log(2), 0) console.log(3)
以上代码,1与3是主线程中的程序,会优先打印,而2是会随后打印,如果主线程中的程序比较耗时的话,那么就会延迟异步的时间,这个时候setTimeout里的时间就不准确了
宏任务
主体script, setTimeout, setInterval
微任务
Promise,process.nextTick
宏任务与微任务的执行顺序是,宏任务先执行,然后再执行微任务
宏任务与微任务举例
console.log('script start') setTimeout(() => { console.log('this is setTimeout1') }, 0) new Promise(resolve => { console.log('promise start') setTimeout(() => { console.log('setTimeout2') resolve() }, 1000) }).then(res => { console.log('then') }) console.log('script end') /**执行流程 * 首先进入主线程 * script start * promise start * script end * 进入event loop中 * setTimout1 * setTimeout2 * 当主线程里的程序执行完后,这个时候会把事件循环里的setTimeout1推入执行栈中,当执行setTimeout1后会 * 进而执行setTimeout2,当setTimeout进行执行栈后,会重新划分宏任务与微任务,所以先执行完setTimeout2后才会执行then里的程序 */
注意:当所有进入主线程中的代码,会重新划分宏任务与微任务,然后会按照宏任务 =》微任务的顺序去执行,也就是宏任务全部执行完后才会执行微任务
script start promise start script end this is setTimeout1 setTimeout2 then
例子二
setTimeout(() => { console.log('this is setTimeout1') }, 0) new Promise(resolve => { console.log('promise start') resolve() }).then(res => { console.log('then') }) // 以上结果会输出 // promise start // then // this is setTimeout1
3、node的模块化(common.js规范)
a、模块化的使用
模块化用来分割,组织和打包软件。每个模块完成一个特定的子功能,所有的模块按某种方法组装起来,成为一个整体,完成整个系统所要求的功能
模块化系统:
1. 定义模块
2. 模块导入(依赖)
3. 模块导出
特点:一个文件就是一个模块, 模块加载采用的同步模式, 通过require函数导入,通过exports对象导出
入门案例
//test.js文件里的内容 let str = 'are you ok???'; exports.str = str; //index.js里的内容 let str = require('./test.js') console.log(str)
注意:这里exports是有带s的,这个要区别开es6语法里的export的用法
模块化的module对象
每个模块中都会有一个内置的对象: module;
该对象提供了包括当前模块文件所拥有的一些信息
Module { id: '.', //唯一的id一般以绝对路径做为唯一的id path: 'C:\\Users\\bill\\Desktop\\test', //所在的文件夹的路径 exports: {}, parent: null, //父级 filename: 'C:\\Users\\bill\\Desktop\\test\\index.js', //文件名 loaded: false, children: [], //子类 paths: [
'C:\\Users\\bill\\Desktop\\test\\node_modules',
'C:\\Users\\bill\\Desktop\\node_modules',
'C:\\Users\\bill\\node_modules',
'C:\\Users\\node_modules',
'C:\\node_modules'
] //保存的是非路径加载模式的路径列表,加载机制是根据文件夹的层级进行逐层查找
}
注意:这里的module.exports与上面例子用的exports是同一个对象,但是在使用的过程是有区别的,相当于exports是全局又定义了的一个对象并且把路径指定module.exports,具体看以下例子
exports.a = 'aaa'; exports.b = 'bbb'; module.exports.c = 'ccc' module.exports.d = 'ddd' //以上两种的赋值方式是一样的,在外部引用的时候都可以得到对应的值 module.exports = { //正确的用法 name: 'name', age: 12 } exports = { //错误的用法,相当于把全局的exports对象的引用的地址切断 name: 'name', age: 12 } //但是注意,如果使用 module.exports = ...的模式赋值的话,全局中允许有一个类似的对象,因为下面会往前覆盖值
b、模块化的分类
File Modules 文件模块模式(以上例子展示的就是文件的模块模式)
Folders as Modules 文件夹的模块模式
node_modules Folders
global floaders
Core Modules 核心的模块模式(node的核心模块,如果fs模块这个优先级最高的)
Folders as Modules
//当引入一个文件夹的时候,没有指定文件,这个时候就会自动加载index.js //如果需要改变这种情况,这个需要就要在指定的文件夹下新建一个package.json,加入如何代码 { "name": "test", "main": "./abc.js" } //这个时候就会默认读取abc.js这个文件,也就是相当于没有package.json文件的时候,系统默认main下的字段是 index.js
node_modules Folders, 而 global floaders是指全局的node_modules
//如果把上面的文件夹取名为test并且放入 node_modules的目录下,这个时候其他模块的引入就可能直接如下 let test = require('test') //这里的test对应的是node_modules下的test文件夹名称
注意:如果模块加载是以 ./ ../ / 开始的,那么就是路径模块加载模式, 不以 ./ ../ / 开始的模块,按照另外一种加载机制进行加载