You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Add a reference to the global object
Local<Object> global = env->context()->Global();
......
// Expose the global object as a property on itself
// (Allows you to set stuff on `global` from anywhere in JavaScript.)
global->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global);
global和process是node中大家经常用到的两个对象,那么这两个对象又是如何被创建的,我们在我们的代码中为什么能够使用呢?本篇文章将为大家揭晓答案。
global
global对象在src/node.cc中的被创建,在bootstrap/node.js中被初始化。
创建
在src/node.cc的LoadEnvironment方法中,有以下几行代码是用来创建global对象的。
其中
env->context()->Global()
获取了当前context中的Global全局对象,global->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global)
将全局对象本身挂载在其global对象上,这样全局对象中有了一个global对象指向了全局对象本身,我们在该context中可以直接使用global对全局对象的引用进行访问。以上程序之后,这样我们就可以在context的任何地方对全局对象进行操作。
初始化
初始化在
bootstrap/node.js
中进行,其在上述逻辑执行后被执行,所以可以直接操作全局对象。初始化代码分为以下几个部分:
1.为global挂载process、Symbol.toStringTag、buffer等属性
这里将process挂载在global上,这也是为什么我们可以在我们的用户代码直接访问process对象的原因。同时注意Symbol.toStringTag属性会在访问global.toString()时访问。
2.初始化timeout、console、URL
这里以setupGlobalTimeouts为例,主要是在global上挂载setImmediate等timeout相关的方法。
3.为global加上'assert', 'async_hooks', 'buffer'等属性
这里调用的是internal/modules/cjs/helpers下的addBuiltinLibsToObject方法,代码如下:
其中builtinLibs主要包含buffer、assert等常用的对象或方法。
process
process在src/env.cc的Environment::Start方法中被创建和初始化,同时在bootstrap/node.js也初始化了process对象。Environment::Start的调用函数是
src/node.cc
中的inline函数Start。创建
在Environment::Start中初始化process的逻辑如下:
这里面主要做了如下几件事:
这里需要注意的是set_process_object是从哪里来的呢?
在env-inl.h中有下面的宏定义:
从这里我们可以看出,set_process_object在这里定义,其真实调用的是process_object_.Reset方法,那么v8::Local:: Reset方法又做了什么呢?
这里Reset方法在PersistentBase类下,这里顾名思义PersistentBase是Persistent handle的基类,调用Reset方法也就是重新给其赋值。
那么开始的Persistent handle process_object又是怎么来的呢?我们看env.h中的如下代码:
其中ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES这个宏我们上面见过,就是调用了多次V,只不过这里的V代表V8的handle声明,用在process_object上其实就是如下代码:
也就是声明了Persistent handle process_object,也就有了我们后面的利用PersistentBase::Reset进行赋值的操作了。
初始化
process的初始化出现在src/env.cc和bootstrap/node.js。
在src/env.cc中,其实调用的是node.cc中的SetupProcessObject方法,初始化代码比较长,下面摘出了比较具有代表性的代码:
这里首先获取从env中获取了process_object,然后设置了一个process.title的存取器,用来获取和设置title,这里的title获取调用了
uv_get_process_title
,实际上就是开辟了堆内存,copy了一份process_argv[0],也就是入口main函数的argv[0];接着使用READONLY_PROPERTY这个宏设置了process的只读属性version。READONLY_PROPERTY宏定义如下所示:在bootstrap/node.js中初始化process的代码如下:
这里主要初始化了process的set_push_values_to_array_function、execPath、错误处理以及国际化版本等。
总结
本文主要讲解了global、process的创建、初始化,以及为什么我们在我们的用户代码中可以对他们进行直接的访问。
The text was updated successfully, but these errors were encountered: