Node.js And C++__2. V8引擎介绍

说明:

V8是node很重要的一个模块,是执行js代码的引擎。我们主要通过使用V8的API来完成C++ 和 Node之间的变量类型转换、异步调用的实现和类的封装等。

主要知识点:

1.Nodejs主要由V8和libuv组成;

2.V8是js运行的引擎;

3.Nodejs变量的创建和内存的释放都是通过V8;

4.V8可以是C++ Addon访问和转换js变量;

5.存储单元在JS和C++中都没有引用的情况下才会被回收;

6.可以把Local 看成 智能指针。

Isolates

1.每一个isolate都有一个独立的堆,保存创建的变量和运行环境;

2.Nodejs只有一个isolate,而且不能再创建;(源码中加锁限制其他线程创建)

3.不能再其他线程中调用isolate;

4.可以把多个V8嵌入C++程序中,是程序可以创建多个isolate,但是要有时候保持isolate的同步是个棘手的问题。

Contexts

1.包含了执行环境和堆:全局变量、变量、函数、系统函数、对象、模块、句柄、文档等等;

2.每个上下文都是独立的,包含自己的运行环境和堆;

3.我们只能通过V8获取、创建、修改上下文的内容。

JavaScript variables, C++ Handles

这里写图片描述

这里写图片描述

HandleScope

1.异步函数和回调参数只能通过HandleScope获取相应的参数;

2.HandleScope不能创建;

3.Local handle 在回调或者C++返回到js的时候进行垃圾回收;

4.在很多例子中都能看到,直接使用了HandleScope,那是因为Nodejs在调用我们写的Addon之前创建了一个HandleScope 对象。

V8 Data Type

这里写图片描述

基本类型

Strings Numbers Booleans null undefined

通过V8 API操作基础数据,而不是直接操作又三个原因:

  • js基本类型的存储机制不可变:js中var x = 5,分配了一个存储单元 a;当 x = 6,a存储单元的值没有改变,而是新建立了一个值为6的存储单元b,x指向b。

  • js调用C++时,通过参数(传值的方式),内部空间对参数的操作不会影响外部变量。

  • Handles能记录变量的引用数,在引用数为零的时候,可以通过垃圾回收机制清空无效引用。

Number -> double
 void PassNumber(const FunctionCallbackInfo<Value>& args) {
 Isolate * isolate = args.GetIsolate();

 // 方式1
 Local<Number> target = args[0]->ToNumber();
 // 方式2
 double value = target->NumberValue();

 // value is now OUTSIDE of V8 - we can use it in
 // all the C++ standard ways.
 }
新建Number并返回
void PassNumber(const FunctionCallbackInfo<Value>& args) {
Isolate * isolate = args.GetIsolate();

// 如果 参数为空,则返回NAN ; NAN+=42 还是等于NAN
double value = args[0]->NumberValue();

value+= 42;

// 新建,必须获取V8内核的独立堆
// 在V8内核的堆上床架一个存储单元,并把value赋值给存储单元
// retval指向这个存储单元
Local<Number> retval = Number::New(isolate, value);
// 返回
 args.GetReturnValue().Set(retval);
 }
JS调用
 const addon = require('./build/Release/primitive');

 var number_returned = addon.pass_number(23);
 console.log(number_returned); // prints 65

 var number_returned = addon.pass_number(0.5);
 console.log(number_returned); // prints 42.5
Number -> int
void PassInteger(const FunctionCallbackInfo<Value>& args) {
    Isolate * isolate = args.GetIsolate();
     // 如果传进来的是是5.7 则v8会自动取整为5
    int value = args[0]->Int32Value();
    Local<Number> retval = Int32::New(isolate, value + 42);
    args.GetReturnValue().Set(retval);
}
Boolean -> bool
void PassBoolean(const FunctionCallbackInfo<Value>& args) {
    Isolate * isolate = args.GetIsolate();
    // Null、未定义、0和空字符串总是被转换为false。
    // 其他一切(包括空对象和数组)都被认为是正确的。
    
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值