v8 回调不适用于堆上的 JavaScript 个对象
v8 callback not working with JavaScript objects on the heap
我创建了一个 JavaScript 对象的实例,例如;
myObj1 = new myObject("Object1");
然后我调用一个 node.js c++ 插件,它会回调 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 class。所以没有实例数据。
根据我过去 2 天的阅读,Call() 方法的第一个参数不知何故变成了 v8 中的 "this" 指针。所以我猜问题可能是我使用的是全局上下文
有人知道如何正确回调堆上的 JavaScript 对象吗?
仅当您 调用 形式为 a.b(...)
或 a[c](...)
的方法时才会设置 this
值,其中 a
是任何表达式并且 b
是属性名称(或 c
是作为属性名称求值的表达式)并且属性值是函数。
需要解包的内容很多,但基本上它的意思是,当您执行 a.b.c(d)
时,存储在 a.b.c
的函数将被调用,表达式 a.b
的值为在该函数的上下文中绑定到 this
。
那是唯一一次这种魔法发生。
因此,当您调用 myAddon.greet(myObj1.name)
时,函数 greet
(从对象 myAddon
获取)被调用,this
被设置为 myAddon
.没有其他魔法发生。特别是, myObj1.name
被评估,发现是一个函数,并且这个函数对象作为参数传递。 未保留从 myObj1
获取函数的详细信息, 这意味着您的 C++ 代码没有可用于获取对该对象的引用的机制!
相反,在 JavaScript 中执行此操作的正确方法是让代码传递回调以根据需要绑定 this
,使用函数的 bind()
方法,如下所示:
myAddon.greet(myObj1.name.bind(myObj1));
您的 C++ 代码将收到一个代理函数对象(bind()
创建一个新函数)。此代理将调用 myObj1.name
函数并将 this
设置为 myObj1
,因此您的 C++ 代码根本不必关心它。
为了说明,表达式 myObj1.name.bind(myObj1)
大致等同于
(function (o, f) {
return function () { return f.apply(o, arguments); };
}(myObj1, myObj1.name))
我创建了一个 JavaScript 对象的实例,例如;
myObj1 = new myObject("Object1");
然后我调用一个 node.js c++ 插件,它会回调 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 class。所以没有实例数据。
根据我过去 2 天的阅读,Call() 方法的第一个参数不知何故变成了 v8 中的 "this" 指针。所以我猜问题可能是我使用的是全局上下文
有人知道如何正确回调堆上的 JavaScript 对象吗?
仅当您 调用 形式为 a.b(...)
或 a[c](...)
的方法时才会设置 this
值,其中 a
是任何表达式并且 b
是属性名称(或 c
是作为属性名称求值的表达式)并且属性值是函数。
需要解包的内容很多,但基本上它的意思是,当您执行 a.b.c(d)
时,存储在 a.b.c
的函数将被调用,表达式 a.b
的值为在该函数的上下文中绑定到 this
。
那是唯一一次这种魔法发生。
因此,当您调用 myAddon.greet(myObj1.name)
时,函数 greet
(从对象 myAddon
获取)被调用,this
被设置为 myAddon
.没有其他魔法发生。特别是, myObj1.name
被评估,发现是一个函数,并且这个函数对象作为参数传递。 未保留从 myObj1
获取函数的详细信息, 这意味着您的 C++ 代码没有可用于获取对该对象的引用的机制!
相反,在 JavaScript 中执行此操作的正确方法是让代码传递回调以根据需要绑定 this
,使用函数的 bind()
方法,如下所示:
myAddon.greet(myObj1.name.bind(myObj1));
您的 C++ 代码将收到一个代理函数对象(bind()
创建一个新函数)。此代理将调用 myObj1.name
函数并将 this
设置为 myObj1
,因此您的 C++ 代码根本不必关心它。
为了说明,表达式 myObj1.name.bind(myObj1)
大致等同于
(function (o, f) {
return function () { return f.apply(o, arguments); };
}(myObj1, myObj1.name))