全局环境

全局环境成员

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.js

3. Console(控制台)


  Node 中内置的 console 模块,提供操作控制台的输入输出功能,常见使用方式与客户端类似。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容