如何在V8中为C ++本机对象实现属性枚举器?

时间:2019-05-22 10:38:51

标签: c++ v8

我正在编写一个与数据库通信的Node.js C ++模块,该模块返回BSON对象,并将它们包装在V8对象中,以便可以从JavaScript对其进行访问。

为此,我创建了一个ObjectTemplate,并通过SetHandler对其进行了配置。我的getter和setter工作,但是属性枚举器不返回任何内容。这是代码:

void PropertyEnumerator(const PropertyCallbackInfo<Array>& info)
{
    // Enumerator, aka `Object.keys(obj)`
    auto isolate = info.GetIsolate();
    auto data = unrwap_internal_field<BsonObjectData>(info.Holder(), 0);

    Local<Array> array = Array::New(isolate);
    int i = 0;

    bson_iter_t iter;
    bson_iter_init_from_data(&iter, data->document_data, data->document_length);

    while (bson_iter_next(&iter)) {
        const char* key = bson_iter_key(&iter);
        array->Set(i++, String::NewFromUtf8(isolate, key, v8::NewStringType::kNormal).ToLocalChecked());
    }

    info.GetReturnValue().Set(array);
}
  • 我已经检查了函数是否真正被调用
  • 我检查了数组是否填充了正确的值

但是在JavaScript中,当我执行console.log(Object.keys(obj))时,我得到了一个空数组。就像info.GetReturnValue().Set(array);什么都不做。文档指出,数组的每个元素都必须是Name,并且String继承自Name,所以我真的不理解。

有想法吗?

1 个答案:

答案 0 :(得分:0)

正如@jmrk在他们的评论中建议的那样,问题是我没有为对象模板实现query function。这使枚举器正常工作:

void PropertyQuery(Local<Name> property, const PropertyCallbackInfo<Integer>& info)
{
    info.GetReturnValue().Set(PropertyAttribute::None);
}