我想设置一种本地化范围,它将像特定函数中的一组全局变量一样,但我想继承可能已经存在的所有全局变量。
然而,必须有一种比我正在做的更容易的方法。
我现在所做的是在javascript中将我想要使用的范围对象转换为由var声明和赋值组成的字符串。我把它放在一个匿名函数中,它返回我原来的函数代码,并调用匿名函数给我内部函数。
MAKESTRING宏使用字符串流来定义字符串
std::prefix_code = convert_object_to_vars(scope);
std::code = MAKESTRING("(function() { " << prefix_code << "return (" << fdefinition << "); })()");
v8::TryCatch try_catch;
v8::Handle<v8::Script> script = v8::Script::Compile(v8::String::NewFromUtf8(_isolate, code.c_str()));
if (try_catch.HasCaught())
return v8::Undefined(_isolate);
if (script.IsEmpty())
return v8::Undefined(_isolate);
v8::Local<v8::Value> result = script->Run();
if (try_catch.HasCaught())
return v8::Undefined(_isolate);
if (!result->IsFunction())
return v8::Undefined(_isolate);
return result
范围变量只是一个v8 :: Object,由键值对组成,描述范围中存在的各种变量及其初始值。
convert_object_to_vars函数让事情变得有点冒险......虽然这似乎有用,但我必须在convert函数中明确地编写代码来处理我想要支持的每个新类型,并且当我添加更多自定义类型时,这个功能在复杂性方面正在快速增长,所以我不相信这是一个长期的解决方案。此外,convert_object_to_vars上的大部分代码也必须在另一个函数中复制,该函数返回此类对象的人类可读表示。
必须有一种更简单的方法。
答案 0 :(得分:0)
我最近在开发我的线程池本机加载项时遇到了这个问题。
使其工作的关键是配置函数将使用您希望在函数中访问的全局变量执行的上下文。
这需要在编译和运行stringified函数之前发生。我在下面给了一个小样本。 myGlobalProperty
将作为函数中的全局函数提供,因为它是在当前输入的上下文中编译和运行的。
// configure context before executing function
HandleScope scope;
Handle<Object> contextObject = Context::GetCurrent()->Global();
contextObject->Set(String::NewSymbol("myGlobalProperty"), Object::New());
// turn function into string
String::Utf8Value funcStr(functionToExecute->ToString());
string funcToExe(*funcStr);
funcToExe.insert(0, "(");
funcToExe.append(")()");
// compile and run the function
// this will execute within the currently entered and configured context
Handle<Script> functionScript = Script::New(String::New(funcToExe.c_str()));
functionScript->Run();
如果要在执行函数后访问全局变量。您需要通过上下文访问它们,如下所示:
Handle<Value> myGlobal = contextObject->Get(String::NewSymbol("myGlobalProperty"));