NodeJS 运行环境
NodeJS 运行环境包含 CommonJS 模块规范、global 全局对象、process 当前进程
CommonJS 模块规范
理解 CommonJS 模块前先来看一个简单的例子:
创建一个 run.js 文件
console.log("This is a test");
之后通过 NodeJS 的 debug 调试工具可以看到
NodeJS 自动给我们创建了一个函数,将我们的代码放置在函数内部,其中 exports 代表我们需要向外暴露的模块或接口;require 表示需要依赖别的模块时调用的 function;module 代表模块本身。
由此我们可以总结出 CommonJS 的几条特性:
1、每个文件都是一个模块,有自己的作用域(每个文件有且只能有一个模块,因为 NodeJS 将其代码放在函数体内,所有都有其自己的作用域)2、在模块内部 module 变量代表模块本身3、module.exports 属性代表模块对外的接口
我们来看一个例子:
创建一个 cusmod.js 文件
console.log("this is a module");
// 定义一个变量
let testVar = 100;
// 定义一个函数
function test(){console.log(testVar);
};
// 将变量与方法暴露出去以便别的文件引用
module.exports.testVar = testVar;
module.exports.test = test;
既然变量与方法已经暴露出去,那么一定会在另一个文件中接收它,那么就有引出了 require 函数,我们先来看一下 require 函数的规则:
1、/ 表示绝对路径,./ 表示相对于当前文件的路径
2、支持 js、json、node 拓展名,不写依次尝试(如果引用的路径不写扩展名,则会依次查找,如果找不到就会报错)
3、不写路径则认为是 node 自带的模块或者是各级 node_modules 内的第三方模块
现在我们新建一个 require.js 去引入 cusmod.js 文件
// 使用 require 引入 cusmod.js 文件(不写拓展名则会依次查找)
let mod = require("./cusmod);
// 打印 cusmod.js 中定义的 testVar
console.log(mod.testVar)
// 调用 cusmod.js 中定义的 test 方法
mod.test();
我们可以看到其输出结果为:
此处不仅将我们暴露的东西打印出来了,还将 cusmod.js 中定义的 console 也打印出来了,由此可以看出在 cusmod.js 中一些没有被暴露出的输出也会被打印出来,所以对于一些不想让用户看见或者不想暴露出来的东西,我们最好将其封装到方法中,等待调用时再获取。
让我们再来看看另一个例子:
创建一个 cache.js 文件
// 引入两次 cusmod.js 文件
require("./cusmod);
require("./cusmod);
看一看输出的结果:
我们可以看到虽然引入了两次 cusmod.js 文件,但是只调用了一次,这就引出了 require 的第一条特性即 module 被加载的时候执行,加载后缓存。
我们再来看看 require 的另一个特性
还是先看一个例子:
创建一个 modA.js 文件
module.exports.test = "A";
let modB = require("./modB");
console.log("modA"+modB.test);
module.exports.test = "AA";
再创建一个 modB.js 文件
module.exports.test = "B";
let modB = require("./modA");
console.log("modB"+modA.test);
module.exports.test = "BB";
最后再创建一个 main.js 文件
let modA = require("./modA");
let modB = require("./modB");
console.log(modA.test);
console.log(modA.test);
最后的输出结果如图所示:
我们根据结果进行分析
首先,main.js 中调用了 modA.js 文件,当 modA.js 执行到 let modB = require("./modB") 这句时会去调用 modB.js 文件,当 modB.js 执行到 let modB = require("./modA") 这句时就形成了对 modA.js 的循环加载,此时当 modB.js 执行到 console.log(“modB”+modA.test)这句时只会输出 modA.js 中已经执行的部分,所以打印出 “modB:A”;当 modB.js 执行完之后又会回到 modA.js 中,而此时 modB.js 中 test 已经变成 BB ,所以输出的结果为 “modA:BB”;这样 main.js 中的第一句就执行完毕了,而由于 “module 被加载的时候执行,加载后缓存”的特性,第二句将不会执行。
综上实例,我们可以得出 require 的两条特性:
1、module 被加载的时候执行,加载后缓存
2、一旦出现某个模块被循环加载,就只输出已经执行的部分,还未执行的部分不会输出
最后,我们再来看一个问题:
还是先看这张图
NodeJS 给我们创建的函数的参数中有一个 exports,另一个参数 module 是一个对象其中也包含这一个 exports,那么它们两个有什么区别呢?
实际上,NodeJS 在创建函数之前有这么一句话"const exports = module.exports",将 module.exports 赋值给了 exports,也就是说它们在某种意义上是相等的,但是有一种情况只可以使用 module.exports 而不能使用 exports,让我们来看下面这个例子:
exps.js
exports.test = 100;
main.js
const mod = require("./exps.js");
console.log(mod.test);
其输出结果为:
这是显而易见的。
但是我们将其改变一下,如下所示:
exps.js
exports = {a : 2,b : 3,test : 100
}
expamain.js 保持不变其输出的结果就会变成:
由此可见,在使用 exports 时,我们可以向其中添加属性,此时 exports 与 module.exports 是一样的,但是如果需要赋值为对象时,我们只能使用 module.exports ,因为使用 exports 会改变 exports 的指向使其不再指向 module.exports 而是指向新赋值的对象,从而导致 exports 不再与 module.exports 相等
global
global 与浏览器中的 window 一样,在浏览器中我们将一些常用的属性放入 window 中以方便使用,而在服务器中则将常用的属性放入了 global 中。
在 global 中的一些属性:
CommonJS
Buffer、process、console
timer
这些属性会在后面做详细了解,我们现在只来看一个例子初步理解一下 global
global.js
const testVar = 1000;
main.js
const mod = require("./global");
console.log(testVar);
此时的输出结果为:
可以看出 testVar 是未定义的。
我们稍微改变一下:
global.js
slobal.testVar = 2000;
main.js
const mod = require("./global");
console.log(testVar);
这次的结果为:
这次结果输出来了,没有报错,说明 testVar 已经添加到全局了
process
process 顾名思义就是进程的意思,它其中包含了许多跟进程执行相关的事件和方法,先来看几个常用的比较重要的对象:
argv – 表示启动 process 时所有的参数,返回的是一个数组
我们举个例子来看一下 argv 所返回的东西
argv.js
const {argv} = process; // ES6 语法引入 process 中的 argv 对象
// 循环遍历 argv 返回的数组
argv.forEach((item) => {console.log(item);
});
其输出结果为:
显而易见,输出的第一个是 NodeJS 所在的位置,第二个当前执行的文件所在的位置。
除此之外,我们还可以添加参数,如图所示:
其输出的结果就会连参数也输出出来。
execArgv – 获取调用 node 所传入的一些特殊参数
修改一下 argv.js
const {execArgv} = process;
console.log(execArgv);
其输出结果为:
可以看出 node 命令后传入的参数被打印出了。
execPath – 获取 node 所在的目录
再来修改一下 argv.js
const {execPath} = process;
console.log(execPath);
其输出结果为:
可以看出其打印的结果就是 NodeJS 所在的目录,其实也就是 argv 返回的数组的第一个。
cwd – cwd 是一个方法,获取当前项目所在的路径
再来修改一下 argv.js
const {cwd} = process;
console.log(cwd());
其输出结果为:
env – 获取一些与环境相关的信息
env.js
const {env} = process;
console.log(env);
其输出结果为:
这就是获取的一些与环境有关的信息。
timer – 包括一些延时调用的命令,setImmediate、setTimeout 以及 process.nextTick
首先来看个例子:
timer.js
setImmediate(() => {console.log("setImmediate");
});setTimeout(() => {console.log("setTimeout");
},0);process.nextTick(() => {console.log("nextTick");
});
其输出结果为:
我们可以看出 process.nextTick 最先输出,setImmediate 最后输出,setTimeout 在它们中间输出。
事实上,setImmediate 是延时调用,它会在下一个事件队列开始时去执行,相当于一个异步,而 process.nextTick 是在当前队列中的东西都执行完后再执行它,因此它比 setImmediate 执行的早,setTimeout 的执行时间则是位于它们中间。
你可能认为 setImmediate 与 process.nextTick 没有什么区别,但事实并非如此,process.nextTick 是在当前事件队列的最后执行,可如果在其中循环调用 process.nextTick 就可能导致程序不能继续向后执行,一直执行 process.nextTick,因此在大部分情况下,我们都使用 setImmediate 。
NodeJS 运行环境相关推荐
- Ubuntu上sublime配置nodejs运行环境
Ubuntu上sublime配置nodejs运行环境 如果阅读无障碍的话可以直接查看https://packagecontrol.io/packages/Nodejs上面说的很详细 如果不想看的话, ...
- 安装NodeJs运行环境
关于大名鼎鼎的Nodejs是什么就不用再介绍了,他的牛逼之处数都数不完--让javascript称霸全宇宙.将一个只用于前端的编程语言同时可以制霸前后端.让致力于前端开发的小哥又多了一项事业新增了一门 ...
- Linux上的node站点之centos配置nodejs运行环境笔记
centos配置nodejs运行环境 原来的项目放在windowsserver上了,现在换个系统要重新配置下. 先看看是不是安装python rpm -qa|grep python 一般租的云服务器会 ...
- nodejs运行环境配置并使用puppeteer实现后台截图
本文目的 不知道小伙伴们有没有遇到过后台截图这样的需求,今天我将自己的经验总结出来分享给大家. 在经过前期的技术调研之后,确定了使用nodejs的puppeteer库实现后台截图,并通过java Ru ...
- 【树莓派不吃灰】基础篇④ Raspberry Pi上搭建NodeJS运行环境
目录 1. 前言 2. 安装NodeJS环境 2.1 安装npm 2.2 安装nodejs 2.3 配置NPM国内镜像源 3. 总结 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️ ...
- Win7搭建NodeJs开发环境以及HelloWorld展示—图解
Windows 7系统下搭建NodeJs开发环境(NodeJs+WebStrom)以及Hello World!展示,大体思路如下:第一步:安装NodeJs运行环境.第二步:安装WebStrom开发工具 ...
- nodejs开发环境搭建
项目场景: 提示:windows 10 环境下搭建nodejs运行环境: 这个事情对大部分人来说,可能不屑一顾.不就是安装上nodejs,然后一步步 npm install, npm run dev ...
- 下载nodejs的mysql安装包下载_nodejs安装包下载|nodejs(javascript运行环境) v5.3.0 最新稳定版 - 软件下载 - 绿茶软件园|33LC.com...
nodejs(javascript运行环境)是款运行在服务器端的javascript.nodejs(javascript运行环境)使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效,Node ...
- NodeJS入门--环境搭建 IntelliJ IDEA
NodeJS入门–环境搭建 IntelliJ IDEA 本人也刚开始学习NodeJS,所以以此做个笔记,欢迎大家提出意见. 1.首先 下载安装NodeJS,下载安装IntelliJ IDEA 2.接下 ...
最新文章
- Linux那些事儿 之 戏说USB(14)端点
- typeof,instanceof 和 isProtoTypeof
- kali工具中文手册_Kali Linux 2019.4发布了!解决Kali Linux 2019.4中文乱码问题
- Vupsen, Pupsen and 0 思维,凑系数
- 软件测试术语中英文对照(部分)
- 【HDU - 1518】Square (经典的dfs + 剪枝)
- linux mysql 5.7密码忘记_Mysql5.7.14 linux版密码忘记的找回方法
- 【渝粤教育】广东开放大学 操作系统原理与应用 形成性考核 (46)
- C# await和async
- mysql分表的原则_分库分表原则 总结
- Excel数据填充技巧
- python实现数据恢复软件手机版下载_知名下载软件,总算出手机版了
- 性能测试第七课--用户定义变量用户参数
- 如何用微信群、微信霸屏进行引流
- 实验二 SQL 语言——SELECT 查询操作(第一部分)
- 蓝桥杯 省赛真题寻找 2020
- Linux 下查询日志
- 【C++】有一个8层灯塔,每层的等数…
- 小米网抢购系统开发实践阅读心得
- 算法基础--《我的第一本算法书》--(算法学习一)