使用v8 shell中的stringify

时间:2012-01-24 18:32:21

标签: javascript v8 stringify

我正在创建一个基于v8 shell的控制台,我使用了v8附带的示例代码并且它运行良好,但是我试图将v8 :: object转换为它的字符串版本(json),但没有找到办法。

这是我在shell.cc中的示例代码:



    v8::Handle test(const v8::Arguments& args) {
        v8::HandleScope handle_scope;
        const char* json;
        v8::String::Utf8Value strJson(args[0]);
        printf(ToCString(json));
        if (args[0]->IsObject()) {
           printf("it's an object\n");
        }
        return v8::String::New("");
    }

在shell中我创建了一个文件test.js:



    var a = {  name: 'John' };
    test(a);

我在shell控制台中执行js后得到了这个:



    [object Object]
    It's an object

我想要的是:



    { "name": "John" }

如果我将js代码更改为:



    var a = { name: 'John'}
    test(JSON.stringify(a));

它工作得很好,但我不希望用户必须知道如何将javascript变量解析为json,我不想检查对象的每一个输入并手动解析它。

有没有办法在C中的shell.cc代码中执行相同的指令?类似的东西:



    v8::Handle<v8::String> temp = JSON.parse(arg[0]);

更新:这就是我处理这个问题的方法,但我想要一个更清洁的方法来做同样的事情:



    const char* toJson(const v8::Local<v8::Object>& obj) {
       std::stringstream ss;
       ss << "{";
       v8::Local<v8::Array> propertyNames = obj->GetPropertyNames();

       for (int x = 0; x < propertyNames->Length(); x++) {
          if (x != 0) {
             ss << ", ";
          }  
           v8::String::Utf8Value name(propertyNames->Get(x));
           ss << "\"" << ToCString(name) << "\":";
           v8::Local<v8::Value> val = obj->GetInternalField(x);
           if (val->IsObject()) {
              ss << toJson(val->ToObject());
           } else {
              ss << "\"" << ToCString(v8::String::Utf8Value(val)) << "\"";
           }  
       }  

       ss << "}";

       const char* result = ss.str().c_str();
       return result;
    }

    v8::Handle test(const v8::Arguments& args) {
        v8::HandleScope handle_scope;
        const char* json;
        v8::String::Utf8Value strJson(args[0]);
        if (args[0]->IsObject()) {
           char* json = toJson(args[0]);
           // ...
           // Some operations with the json
           // ...
        }
        return v8::String::New("");
    }

3 个答案:

答案 0 :(得分:10)

我使用内置JSON.parse函数的v8s找到了这种反向方式(JSON到v8对象)。 http://www.mail-archive.com/v8-users@googlegroups.com/msg04430.html

调整此项以使用JSON.stringify会看起来像这样(未经测试):

Handle<String> toJson(Handle<Value> object)
{
    HandleScope scope;

    Handle<Context> context = Context::GetCurrent();
    Handle<Object> global = context->Global();

    Handle<Object> JSON = global->Get(String::New("JSON"))->ToObject();
    Handle<Function> JSON_stringify = Handle<Function>::Cast(JSON->Get(String::New("stringify")));

    return scope.Close(JSON_stringify->Call(JSON, 1, object));
}

答案 1 :(得分:0)

我想避免使用现已弃用的V8方法来实现negative到 - v8::Value转换,因此我将这个功能放在一起,从Michael的回答中汲取灵感。缺点是它非常冗长:

string

答案 2 :(得分:0)

如果您使用的是更新的V8(如8.3),则代码如下:

setNames(do.call("rbind", lapply(category, cbind, dates1)), c("category", names(dates1)))