本文转载自微信公众号《编程杂技》,作者theanarkh。转载本文请联系编程杂技公众号。越来越多的同学在使用Node.js,每个人都不同程度地理解Node.js是什么。例如,Node.js由V8、Libuv和JS组成。Node.js的底层是C\C++。Node.js不是一种语言,而是一种运行时。本文通过实现一个类似Node.js的JS运行时No.js来理解Node.js的本质。No.js是我之前写的一个JS运行时,概念上的,但它不是真正的运行时,它只是一个demo,但它向你展示,如果你有兴趣,你也可以写一个Node.js。js。首先,让我们看一下V8的基本用法。#include#include#include#include"include/libplatform/libplatform.h"#include"include/v8.h"intmain(intargc,char*argv[]){//InitializeV8.v8::V8::InitializeICUDefaultLocation(argv[0]);v8::V8::InitializeExternalStartupData(argv[0]);std::unique_ptrplatform=v8::platform::NewDefaultPlatform();v8::V8::InitializePlatform(platform.get());v8::V8::Initialize();v8::Isolate::CreateParamscreate_params;create_params.array_buffer_allocator=v8::ArrayBuffer::Allocator::NewDefaultAllocator();//创建一个Isolate,代表一个隔离实例v8::Isolate*isolate=v8::Isolate::New(create_params);{v8::Isolate::Scopeisolate_scope(isolate);//定义AHandleScope下面管理句柄内存的分配和释放v8::HandleScopehandle_scope(isolate);//创建上下文,js中访问的东西来自contextv8::Localcontext=v8::Context::New(isolate);v8::Context::Scopecontext_scope(context);//定义我们要执行的代码v8::Localsource=v8::String::NewFromUtf8(隔离,"'Hello'+',World!'",v8::NewStringType::kNormal).ToLocalChecked();//编译脚本v8::Localscript=v8::Script::Compile(context,source).ToLocalChecked();//执行脚本v8::Localresult=script->Run(context).ToLocalChecked();//输出结果v8::String::Utf8Valueutf8(isolate,result);printf("%s\n",*utf8);}//DisposetheisolateandteardownV8.isolate->Dispose();v8::V8::Dispose();v8::V8::ShutdownPlatform();删除创建参数。array_buffer_allocator;return0;}我们看到了很多代码,但是大部分都是基于V8文档的。核心是上下文和脚本的定义。我们看到这里的上下文是V8提供的内容,然后执行的JS脚本也是普通的。接下来我们要做的是扩展这个上下文并向其中注入新的功能。相应的,在JS中也可以访问V8内置变量以外的变量。让我们看看如何去做。//获取一个全局变量,这是我们在js中对应的全局变量Local