首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将JSObject转换为映射(反之亦然)或列出JSObject成员

如何将JSObject转换为映射(反之亦然)或列出JSObject成员
EN

Stack Overflow用户
提问于 2012-07-05 19:10:49
回答 3查看 3.4K关注 0票数 4

Javascript中,我有以下代码:

代码语言:javascript
复制
var r=applet.foo({var0:99,var1:'foo',var2:applet});

在我的小程序中,我有以下内容:

代码语言:javascript
复制
public JSObject foo(JSObject args){
    System.out.println("The function is correctly invoked");
    //In fact, the following works perfectly:
    System.out.println("var1 is:"+(String)args.getMember("var1"));
    JSObject w=JSObject.getWindow(this);
    JSObject j=(JSObject)w.eval("new Object();");
    Map m=new Hashmap();

    //TODO here all the keys and values of args should be added to m

    m.put("hello","world");

    //TODO here all the keys and values of m should be added to j

    return j;
}

如何做到这一点?(TODOs)

在阅读06.html时,我注意到JSObject有一个getSlot方法,但如果有

代码语言:javascript
复制
args.getSlot(0)

我只有一个例外:

代码语言:javascript
复制
netscape.javascript.JSException: No such slot 0 on JavaScript object
...
EN

回答 3

Stack Overflow用户

发布于 2012-12-20 23:33:06

不幸的是,Errandir的解决方案只有在您知道全局变量的名称时才有效,该名称可用于访问您希望获得属性名称的对象。您需要知道这个名称才能将keys方法添加到对象中,并在稍后使用JSObject打电话方法调用它。当然,如果您有对象的全局名称,则可以将它的全局名称传递给Java。这个解决方案看起来不太好,特别是当您不能在全局上下文中引用对象时。

作为另一种选择,我建议在评论中使用this of JSObject评估方法,前提是它可以完成所有工作。但令人失望的是,它只能在Mozilla和Opera中正常工作。在Internet 9和Google (在Windows 7和Ubuntu12.04 LTS下测试)中,eval方法总是引用applet的文档窗口,忽略JavaScript对象JSObject实例实际上代表的内容。我不知道它是一个bug,还是这些浏览器支持的LiveConnect非常糟糕。

好消息是,call方法的JSObject在适当的上下文上执行指定的函数。记住这一点,我终于找到了一个如何检索JavaScript对象属性名称列表的解决方案。其思想是使用eval方法在全局上下文中定义一个临时函数。此函数必须接收我们希望获得属性的JavaScript对象,并将这些属性的名称作为数组返回。然后,通过JSObjectcall方法调用临时函数,传递相关JavaScript对象的jsObject表示(以下方法中的jsObject或问题中的args ),最后删除临时函数。

代码语言:javascript
复制
public static ArrayList<String> getJsObjectPropertiesNames(Applet applet, JSObject jsObject) {

    if (applet == null || jsObject == null)
        return null;

    // Retrieving global context - a JSObject representing a window applet belongs to
    JSObject globalContext;
    try {

        globalContext = JSObject.getWindow(applet);
    }
    catch (JSException ex) {

        return null;
    }

    // Checking whether passed object is not an array
    try {

        jsObject.getSlot(0);
        return null;
    }
    catch (JSException e) {

    }

    String keysFunctionName = String.format("_getKeys%d", Calendar.getInstance().getTimeInMillis());
    jsObject.eval("window['" + keysFunctionName + "'] = function(jsObject) { return Object.keys(jsObject) }");
    JSObject propertiesNamesJsObject = (JSObject)globalContext.call(keysFunctionName, new Object[] { jsObject });
    jsObject.eval("delete(window['" + keysFunctionName + "'])");

    ArrayList<String> propertiesNames = new ArrayList<>();
    try {

        int slotIndex = 0;
        while (true) {

            Object propertyName = propertiesNamesJsObject.getSlot(slotIndex);
            if (propertyName instanceof String)
                propertiesNames.add((String)propertyName);
            slotIndex++;
        }
    }
    catch (JSException e) {

    }

    return propertiesNames;
}
票数 3
EN

Stack Overflow用户

发布于 2012-10-17 10:21:10

作为一种解决方案,您可以将方法keys定义为建议的这里 (您可以在java代码中使用JSObject.eval(...)完成它)。然后你就可以得到这样的钥匙:

代码语言:javascript
复制
JSObject keys = (JSObject)args.call("keys", Collections.EMPTY_LIST);
keys.getSlot(0);
票数 1
EN

Stack Overflow用户

发布于 2015-08-07 02:13:52

在这里,我打印一个字符串,请修改它,以获得任何您需要的。

代码语言:javascript
复制
public final static String getKeys = "{var keys = [];for (var key in this) {keys.push(key);} keys;}";

private static String printProperties(final Object o,
                                      final boolean printType,
                                      final int level,
                                      final String tab) {
    final StringBuilder sb = new StringBuilder(100);
    if (printType) {
        sb.append("(");
        sb.append(o.getClass().getSimpleName());
        sb.append(") ");
    }
    if (o instanceof JSObject) {
        sb.append("{\n");
        final JSObject js = (JSObject) o;
        final JSObject keys = (JSObject) js.eval(getKeys);
        boolean needComma = false;
        for (int i = 0;; i++) {
            final String key = (String) keys.getSlot(i);
            if ((key != null) && !(key.equals("undefined"))) {
                final Object val = js.getMember(key);
                if (!needComma) {
                    needComma = true;
                } else {
                    sb.append(",\n");
                }
                sb.append(multitab(tab, level));
                sb.append(key);
                sb.append(":");
                sb.append(printProperties(val, printType, level + 1, tab));
            } else {
                break;
            }
        }
        sb.append("\n");
        sb.append(multitab(tab, level - 1));
        sb.append("}");
    } else {
        sb.append(o);
    }
    return sb.toString();
}

private final static String tab = "  ";

private static String multitab(final String tab,
                               int i) {
    final StringBuilder sb = new StringBuilder();
    while (i-- > 0) {
        sb.append(tab);
    }
    return sb.toString();
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11350967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档