v8回调不能与堆上的JavaScript对象一起使用

时间:2017-04-10 17:58:52

标签: javascript c++ callback node.js-addon

我创建了一个JavaScript对象的实例,比如;

myObj1 = new myObject("Object1");

然后我调用node.js c ++ addon,它对Javascript对象进行回调...

myAddon = require('myAddon');
myAddon.greet(myObj1.name);

c ++回调代码如下所示:

Local<Function> callback = Local<Function>::Cast(args[0]);
Isolate* isolate = args.GetIsolate();
const int argc = 1;
const char *parm = "Hello";
v8::Local<v8::Value> argv[argc] = {  v8::String::NewFromUtf8(isolate, parm) };
callback->Call(isolate->GetCurrentContext()->Global(), argc, argv);

但问题是绑定不会回调到myObject的实例,而是回调到基类JavaScript类。所以没有实例数据。

从过去2天我能够阅读的内容来看,Call()方法的第一个参数在某种程度上变成了v8中的“this”指针。所以我猜测问题可能是我正在使用全局上下文

有没有人知道如何正确回调堆上的JavaScript对象?

1 个答案:

答案 0 :(得分:1)

this值仅在您调用 a.b(...)a[c](...)形式的方法时设置,其中a是任何表达式{ {1}}是属性名称(或b是评估为属性名称的表达式),属性值是函数。

解压缩了很多,但基本上它意味着当你执行c时,调用存储在a.b.c(d)的函数,并将表达式a.b.c的值绑定到a.b在该函数的上下文中。

这是这种神奇发生的唯一时间。

因此,当您调用this时,调用函数myAddon.greet(myObj1.name)(从对象greet获取),并将myAddon设置为this。没有其他魔法发生。特别是,myAddon被评估,被发现是一个函数,并且该函数对象作为参数传递。 myObj1.name获取函数的详细信息未保留,表示您的C ++代码没有用于获取对此对象的引用的机制!

相反,在JavaScript中执行此操作的正确方法是使用bind()函数方法将代码传递回绑定myObj1的代码,如下所示:

this

您的C ++代码将收到代理函数对象(myAddon.greet(myObj1.name.bind(myObj1)); 创建一个新函数)。此代理将调用bind()函数并将myObj1.name设置为this,因此您的C ++代码无需关心它。

为了说明,表达式myObj1大致相当于

myObj1.name.bind(myObj1)