Javascript 将值绑定到脚本中提到的变量

Javascript 将值绑定到脚本中提到的变量,javascript,gwt,eval,Javascript,Gwt,Eval,我正在创建一个Java库的GWT版本,它支持javax.script.ScriptEngine通过Javascript动态评估函数,例如 o => o % 2 == 0 其中,在运行时,“o”的值是通过javax.script.Bindings定义的(当然,o=>部分被剥离) 问题是,如何从GWT内部获得相同的效果?我使用本机函数 native Object nativeEval(String script) /*-{ return $wnd.eval(script); }-*/

我正在创建一个Java库的GWT版本,它支持javax.script.ScriptEngine通过Javascript动态评估函数,例如

o => o % 2 == 0
其中,在运行时,“o”的值是通过javax.script.Bindings定义的(当然,
o=>
部分被剥离)

问题是,如何从GWT内部获得相同的效果?我使用本机函数

native Object nativeEval(String script) /*-{
    return $wnd.eval(script);
}-*/

nativeEval("o % 2 == 0");

但是如何将值绑定到标识符“o”?

将值传递到标识符“o”:

然后称之为:

String script = "o % 2 == 0";
define("o",2);
Window.alert(nativeEval(script)+"");
define("o",3);
Window.alert(nativeEval(script)+"");

我想我找到了一个解决办法:

import javax.script.bindings.Bindings;
import javax.script.bindings.SimpleBindings;

int bindSequence;

native void prepareOnWindow(int index) /*-{
    $wnd["mylib_bindings_" + index] = new Array();
}-*/;
native void setOnWindow(int index, String name, Object value) /*-{
    $wnd["mylib_bindings_" + index][name] = value;
}-*/;
native void clearOnWindow(int index) /*-{
    $wnd["mylib_bindings_" + index] = null;
}-*/;
native Object invoke(String script) /*-{
    var result = $wnd.eval(script);
    if (typeof(result) == "boolean") {
        return result ? @java.lang.Boolean::TRUE : @java.lang.Boolean::FALSE;
    } else
    if (typeof(result) == "number") {
        return @java.lang.Double::valueOf(D)(result);
    }
    return result;
}-*/;
public Object invoke(String script, Bindings bindings) {
    int seq = bindSequence++;
    try {
        StringBuilder script2 = new StringBuilder();
        prepareOnWindow(seq);
        for (Map.Entry<String, Object> e : bindings.entrySet()) {
            setOnWindow(seq, e.getKey(), e.getValue());
            script2.append("var ").append(e.getKey()).append(" = ")
            .append("window[\"mylib_bindings_\" + ").append(seq)
            .append("][\"").append(e.getKey()).append("\"];\r\n");
        }
        script2.append("\r\n").append(script);
        return invoke(script);
    } finally {
        clearOnWindow(seq);
    } 
}

void testing() {
    Bindings b = new SimpleBindings();

    b.put("o", 1);

    Window.alert(invoke("o", b).toString());

    b.put("o", "Hello world");

    Window.alert(invoke("o", b).toString());

    b.put("o", 2);

    Window.alert(invoke("o % 2 == 0", b).toString());
}
import javax.script.bindings.bindings;
导入javax.script.bindings.SimpleBindings;
int序列;
本机void窗口(int索引)/*-{
$wnd[“mylib_绑定”+索引]=新数组();
}-*/;
本机void setOnWindow(int索引、字符串名称、对象值)/*-{
$wnd[“mylib\u绑定”+索引][名称]=值;
}-*/;
本机void clearOnWindow(int索引)/*-{
$wnd[“mylib\u绑定”+索引]=null;
}-*/;
本机对象调用(字符串脚本)/*-{
var result=$wnd.eval(脚本);
if(typeof(result)=“boolean”){
返回结果?@java.lang.Boolean::TRUE:@java.lang.Boolean::FALSE;
}否则
if(类型(结果)=“编号”){
return@java.lang.Double::valueOf(D)(结果);
}
返回结果;
}-*/;
公共对象调用(字符串脚本、绑定){
int-seq=bindSequence++;
试一试{
StringBuilder script2=新的StringBuilder();
准备窗口(seq);
对于(Map.Entry e:bindings.entrySet()){
设置窗口(seq,e.getKey(),e.getValue());
script2.append(“var”).append(e.getKey()).append(“”)
.append(“窗口[\”mylib\u绑定\“+”)。append(seq)
.append(“][\”).append(e.getKey()).append(“\”];\r\n”);
}
script2.append(“\r\n”).append(脚本);
返回调用(脚本);
}最后{
clearOnWindow(seq);
} 
}
无效测试(){
绑定b=新的SimpleBindings();
b、 付诸表决(“o”,1);
alert(调用(“o”,b).toString());
b、 放置(“o”,“你好,世界”);
alert(调用(“o”,b).toString());
b、 put(“o”,2);
alert(调用(“o%2==0”,b).toString());
}
其思想是在一个常见的可访问对象(如window)上设置名称-值对,并修改脚本以从中获取变量。为了允许可重入调用,绑定存储在不断增加的序列号下

new Function("o", "return (" + expressionThatUsesO + ")")(o)
如果使用so的
表达式是
“o%2”
,则这相当于立即调用的全局函数

(function (o) { return o % 2; })(o)
作为参考:

参数

arg1,arg2。。。argN

函数用作形式参数名称的名称。每个字符串都必须是一个对应于有效JavaScript标识符的字符串,或者是一个用逗号分隔的字符串列表;例如
“x”
“theValue”
,或
“a,b”

functionBody

包含构成函数定义的JavaScript语句的字符串


您的解决方案仅适用于具有有意义的字符串表示形式的类型。我不确定第一个变量是否与第二个变量具有相同的上下文?你能给我一个没有有意义的字符串表示的类型的例子吗?是的,它们有相同的上下文
(function (o) { return o % 2; })(o)
new Function ([arg1[, arg2[, ... argN]],] functionBody)