常见的 Node.js 全局对象

本文正在参与技术专题征文Node.js进阶之路,点击查看详情

通常在浏览器的控制台,我们可以直接打印查看 window,因为在浏览器 JavaScript 中, window 是全局对象(Global Object),是在程序的任意位置都可以访问的对象。而在 Node.js(下面简称 node) 中,与之相对应的全局对象则是 global。查看 node 的官方文档,左侧菜单栏点击 Globals 可以看到 node 中有很多的全局对象:

image.png
本篇文章先简单地介绍几个常见的 node 中的全局对象。

__dirname

__dirname 是当前执行的 js 文件的目录的绝对路径。比如我们直接在 test.js 文件中打印 __dirname:console.log(__dirname),在终端中通过 node 执行 test.js,结果如下图:

image.png

可以看到返回的是 test.js 所在的目录的绝对路径。

__filename

__filename 是当前执行的 js 文件的绝对路径,打印执行 console.log(__filename) 结果如下图:

image.png

其与 __dirname 的区别就在于一个是执行文件本身的绝对路径,另个一是执行文件的目录的绝对路径。

特别说明

准确地说,__dirname,以及 __filename 和 exports 实际上是每个模块中的变量,如果通过 node 的 REPL 去打印这些对象,会如下图所示,结果都是 not defined,而不是像其它全局对象(比如 process)会返回对象内容:

image.png

console

console 最初是由 IE 浏览器的 JScript 引擎提供的调试工具,后来成为了浏览器的实施标准,node 对此标准进行了沿用。所以前面我们在测试 __dirname 或 __filename 的时候,可以直接使用 console 对象。因为 console 也是 node 中的一个全局对象,用于 node 程序的输出。除了我们平常最常用到的 console.log() 方法,还有好几个,比如 console.info()console.error()等,下面详细介绍 2 个:

  • console.clear()——用于清空之前的 console 输出:
// test.js
console.log(__filename)
console.info(__dirname)
console.clear()
console.log('只有我会被打印')
复制代码

执行上面这段代码的结果如下:

image.png

第 2、3 行的 console 信息都被清除了;

  • console.trace()——当前执行的代码在堆栈中的调用路径,比如我们可以在函数中使用,以查看函数的调用栈:
// test.js
function fa() {
  fb()
}
function fb() {
  fc()
}
function fc() {
  console.trace()
}
fa()
复制代码

执行结果如下图:

image.png

由上图可知,console.trace() 在 fc 函数中执行,fc 被 fb 调用, fb 被 fa 调用,而 fa 则是被当做了匿名函数(Object.<anonymous>)进行的调用。如果在浏览器中执行 test.js,那么输出结果到 (anonymous) 就结束了,但是在 node 中可以看到后面还有好几次调用,这些涉及到当前 js 文件的编译(Module._compile)、扩展名(Object.Module._extensions..js)、加载(Module.load)等内容了,具体可以去 github 的 node 源码中查看,比如 Module._compile 的定义就可以在下图所示的位置查看到:

image.png

定时器

node 的全局对象还包括 setInterval()/clearInterval()setTimeout()/clearTimeout()setImmediate()/clearImmediate() 函数,所以我们在 node 中也可以像在浏览器环境中一样使用定时器方法。

process

process 对象提供了 node 进程相关的信息,包括 node 的版本、运行环境、参数信息甚至是 v8 引擎的版本,CPU架构信息等:

image.png

当我们通过 node 去执行一个 js 文件的时候,会在操作系统中开启一个进程——负责为程序的运行提供必备的环境,对应的还有个概念叫做线程——是计算机中的最小的计算单位,负责执行进程中程序。记得之前有个老师说过,你可以把进程当做是工厂中的车间,而线程就是车间里的工人。

给 node 传递参数

process 对象里有个属性叫做 argv,可以接收我们传递给 node 的参数。传递参数的方法很简单,就是在输入 node 文件名.js 执行的时候,后面直接跟上要传递的参数即可,比如:

node test.js Jay occupation=singer
复制代码

这样,我们在 test.js 中进行打印 console.log(process),可以在 process 对象里找到 argv 属性,它是个数组,里面默认的前两个元素分别是 node 所在的绝对路径和我们当前执行的文件的绝对路径,之后的元素就是我们传入的参数了:

image.png

argv 是 argument vector 的缩写,vector 在 c++ 或 java 中是一种数组数据结构。

global

global 对象是比较特殊的一个全局对象,我们前面讲的 console 和 process 都有被放入到 global 中,直接获取 process 和通过 global.process 获取到的对象是一样的。此外,global 身上还有非常多的属性,我们可以在 node 的 REPL 中输入 global.,注意 global 后面有个点,然后按两次 tab 键查看其所有属性:

image.png

其本身的属性里还有个 global,有点像浏览器环境下的 window 对象。但也有区别,比如在浏览器环境下,我们在全局作用域中通过 var 声明一个变量,该变量会被自动加入到 window 对象中;但是在 node 中,如果我们在 js 文件中直接 var 声明一个变量,是不会被放入到 global 对象中的。因为在 node 里一个 js 文件只是一个独立的模块而已,所以我们在其中声明的变量并不会是一个全局的变量。

源码

如果想查看 node 源码中是如何给 global 添加属性的,比如 process,可以通过下图所示的路径查看:

image.png

One More Thing

前文中多次提及一个概念叫做 node 的 REPL,那么它是什么东西呢?在命令行工具直接输入 node 然后按下回车,就会进入 node 的 REPL(Read-Eval-Print Loop),也就是“读取-求值-输出 循环”,是一个简单的交互式的编程环境。然后我们就可以像在浏览器控制台那样,写一些 js 代码执行。想退出 REPL 按 ctrl + c 即可。

感谢.gif 点赞.png

猜你喜欢

转载自juejin.im/post/7083302382427176991