全局环境成员
1. Global(全局变量)
global 类似于客户端 JavaScript 运行环境中的 window,指全局里面的所有成员。
注意:真正的全局成员其实只有 process 和 console 以及 global,其余的都是模块内的伪全局成员。
2. Process(进程)
Process 用于获取当前的 Node 进程信息,一般用于获取环境变量之类的信息。
(1) process.argv
process.argv
属性返回一个数组,这个数组包含了启动 Node.js 进程时的命令行参数。第一个元素为 process.execPath。
如果需要获取 argv[0]
的值请参见 process.argv0
。第二个元素为当前执行的 js 文件路径。剩余的元素为其他命令行参数。
/* print process.argv */
var argv = process.argv;
console.log("我是 process.argv:", argv); // 返回 process.execPath 和当前执行的 js 文件路径……
console.log("我是 process.argv0:", argv[0]); // 返回 process.execPath
console.log("我是 process.argv1:", argv[1]); // 返回 当前执行的 JavaScript 文件路径
console.log("我是 process.argv2:", argv[2]); // 若没有第三个参数,则返回 undefined
process.argv
举例(把以下代码另存为一个单独的文件,并命令为 Argv.js
):
var Argv = process.argv.slice(2); // 由于 process.argv 返回的数组中前两个元素通常没什么用,这里用 slice() 方法去掉了前两个元素
switch (Argv[0]) {
case 'init':
console.log("你需要 init");
break;
case 'install':
var installPackageName = Argv[1];
console.log("正在安装 " + installPackageName + " ……");
break;
case 'uninstall':
console.log("正在卸载,请稍后……");
break;
}
以上代码执行的结果:
Argv.js(2) process.env
process.env
属性返回一个包含用户环境信息(环境变量)的对象。
例如这样的对象:
{
TERM: 'xterm-256color',
SHELL: '/usr/local/bin/bash',
USER: 'maciej',
PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
PWD: '/Users/maciej',
EDITOR: 'vim',
SHLVL: '1',
HOME: '/Users/maciej',
LOGNAME: 'maciej',
_: '/usr/local/bin/node'
}
(3) process.stdin(标准输入)
process.stdin
属性返回连接到 stdin (fd 0)
的流。
以下代码用来在控制台采集数据,并且把采集到的数据打印到终端(把以下代码另存为一个单独的文件,并命令为 stdin.js
):
process.stdout.write("这里输入:");
process.stdin.on('data', (input) => { // 当前命令行中出现回车符键时会触发会出发此事件。这里 data 是事件类型,input 作为形参是输入的数据(同时也是一个作为流的二进制数组)
process.stdout.write("这里输出:" + input); // 要注意的是 process.stdout.write() 会把回车键当做一个可显示的字符输出到控制台
process.stdout.write("按两次 [Ctrl] + C 退出!");
});
以上代码执行的结果:
stdin.js以下代码实现在控制台进行登录(把以下代码另存为一个单独的文件,并命令为
login.js
):
/* 这里定义一个对象用来保存用户和密码 */
var users = {
"user1": "111",
"user2": "222",
"user3": "333"
};
/* 在控制台输出第一个问题 */
process.stdout.write("请输入用户名:");
/* 为用户名设置一个用来判断的标识符 username,这个标识符用来判断当前采集的数据是用户名还是密码 */
var username = ""; // 若 username = "",则把当前输入的数据作为用户名去采集,否则当做密码去采集
/* 当控制台检测到有输入时(当键盘上的回车键被敲下时)采集输入的数据,即当前命令行中出现回车符键时会触发会出发 process.stdin.on("data", (input) => {} 这个事件 */
process.stdin.on("data", (input) => { // 在 process.stdin.on("data", (input) => {} 中,data 是事件类型;input 作为形参是输入的数据
/*===============================================================================================================================================
这里可以检测一下输入的数据 input 以及 input 的数据类型是啥?
process.stdout.write("I am input:" + input); // 这里输入的数据 input 实际上是一个流(二进制数组),不是字符串
process.stdout.write("I am typeof(input):" + typeof(input) + "\n"); // 返回 object
===============================================================================================================================================*/
/* process.stdout.write() 会把回车键当做一个字符去输出,在这里必须把回车键给去掉 */
input = input.toString().trim(); // 由于输入的数据 input 实际上是一个流,所以要把输入流转换为字符串并且去除字符串两端的空白字符
/* 使用 if....else 语句在条件为 true 时执行代码,在条件为 false 时执行其他代码 */
if (!username) { // 判断当前键入的数据是用户名还是密码,当 username = "" 时去采集用户名,否则去采集密码
/*=====================================================================================================
这可以检查一下当 username = "" 时,Boolean(username) 的值以及 !username 的值什么?
process.stdout.write("I am username:" + username + "\n");
process.stdout.write("I am Boolean(username):" + Boolean(username) + "\n"); // 返回 false
process.stdout.write("I am !username:" + !username + "\n"); // 返回 true
=====================================================================================================*/
/* 判断输出的数据 input 是否存在于 users 这个对象中 */
/* Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性(键名)组成的数组,即获取一个对象中的键值对集合中所有的键组成的数组 */
if (Object.keys(users).indexOf(input) === -1) { // 如果键入的数据 input 不存在于 users 这个对象中,则令 username = "",否则用 username 保存当前采集到的用户名
process.stdout.write("用户名不存在,请重新输入用户名" + "\n"); // 等待下一次控制台输入事件触发
username = "";
} else {
process.stdout.write("用户名存在!请输入密码:");
username = input; // 用 username 保存当前采集到的用户名
}
} else { // 假如 username != "",那么 !username 则为 false,这时候就要把当前输入的数据作为密码去采集
/* 这里把 username 保存的用户名作为 users 这个对象的下标去查找相应的键值,并与当前用 input 采集到的密码做对比 */
if (input === users[username]) { // 密码正确
process.stdout.write("登陆成功!3 秒钟后退出此界面!");
setTimeout( () => { // 设置定时器 3 秒钟后退出当前界面
process.exit()
}, 3000);
} else { // 密码错误
process.stdout.write("密码错误!\n请重新输入密码:\n");
}
}
});
以上代码执行的结果:
login.js(4) process.stdout(标准输出)
process.stdout.write()
向控制台输出内容。
可以把 console.log()
和 process.stdout.write()
二者视作等价:
console.log = (msg) => {
process.stdout.write(`${msg}\n`);
};
以下代码用于向控制台输出字符画(把以下代码另存为一个单独的 js 文件,并命名为 animation.js):
① 不断地切换显示的图形(字符画);
② 擦除重绘。
/* 设置字符动画的成员,每个成员就是一帧(以下字符串的写法为 ES6 的模板字符串)*/
var frames = [];
frames[frames.length] = `
╭~~~╮
(o^.^o)
`;
frames[frames.length] = `
╭~~~╮
(o~.~o)
`;
frames[frames.length] = `
╭~~~╮
(o@.@o)
`;
frames[frames.length] = `
╭ ﹌╮
(o'.'o)
`;
/* 把 current 设置为当前帧的标识符:当前显示的帧(哪一帧) */
var current = 0;
/* 向控制台输出字符动画 */
var render = () => { // ES6 箭头函数
/* 以下两行代码用于清空当前控制台 */
process.stdout.write('\033[2J');
process.stdout.write('\033[0f');
/* 输出新的内容 */
if (current === frames.length) { // 如果当前帧等于 frames.length,则将当前帧数的标识符 current 清零
current = 0;
}
/* 向控制台输出当前字符画(帧)*/
process.stdout.write(frames[current++]);
}
/* 设置 setInterval 的周期为 1000/fps 毫秒,即令控制台以每 1000/fps 毫秒输出一帧字符画 */
var fps = 10;
setInterval(render, 1000 / fps);
以上代码执行的结果:
animation.js process.stdout.write()
也可以把从本地文件中读取的内容输出到终端,此处以读取 1.txt ~ 6.txt
中的内容为例(把以下代码另存为一个单独的 js 文件,并命名为 fs-print.js
):
/* 导入文件系统模块(fs)*/
var fs = require("fs");
/* 设置字符文件的成员,每个文件为一帧 */
var frames = [];
for (var i = 1; i < 7; i++) {
/* fs.readFileSync(path, [options]) 以同步的方式读取一个文件的全部内容。此处读取 1.txt ~ 6.txt 文件中的内容(内容可以自定义,这里只是做一个示例)*/
frames[frames.length] = fs.readFileSync(`./frames/${i}.txt`, "utf8"); // `./frames/${i}.txt` 为 ES6 的模板字符串写法
}
/* 把 current 设置为当前帧的标识符:当前显示的帧(哪一帧) */
var current = 0;
/* 向控制台输出文件内容 */
var render = () => { // ES6 箭头函数
/* 以下两行代码用于清空当前控制台 */
process.stdout.write('\033[2J');
process.stdout.write('\033[0f');
/* 输出新的内容 */
if (current === frames.length) { // 如果当前帧等于 frames.length,则将当前帧数的标识符 current 清零
current = 0;
}
/* 向控制台输出当前文件(帧)*/
process.stdout.write(frames[current++]);
}
/* 设置 setInterval 的周期为 1000/fps 毫秒,即令控制台以每 1000/fps 毫秒输出一个文件的内容 */
var fps = 10;
setInterval(render, 1000 / fps);
在 fs-print.js
的同一级目录下创建一个 frames
目录,把要读取的文件(1.txt ~ 6.txt)放入 frames
目录中,文件结构如下:
以上代码执行的结果:
fs-print.js3. Console(控制台)
Node 中内置的 console 模块,提供操作控制台的输入输出功能,常见使用方式与客户端类似。
网友评论