本文介绍了从JavaScript调用@JSFunction,TypeError:找不到对象的默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我正在调用 @JSFunction 带注释的 ScriptableObject方法 JavaScript文件The JavaScript fileTarget = Packages.com.acme.rhino.Target;function evaluate() { var t = Target(); t.addModifier("foobar", 1); return t;} Java文件public class Target extends ScriptableObject { private static final long serialVersionUID = 1L; public List<Modifier> modifiers = new LinkedList<>(); @JSConstructor public Target() { } @JSFunction public void addModifier(final String message, final int value) { modifiers.add(new Modifier(message, value)); } public int getValue() { int sum = 0; for (final Modifier modifier : modifiers) { sum += modifier.getValue(); } return sum; } @Override public String getClassName() { return "Target"; }}但是我得到了org.mozilla.javascript.EcmaError: TypeError: Cannot find default value for object. at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3687) at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3665) at org.mozilla.javascript.ScriptRuntime.typeError(ScriptRuntime.java:3693) at org.mozilla.javascript.ScriptRuntime.typeError1(ScriptRuntime.java:3705) at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:976 ) at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:895 ) at org.mozilla.javascript.ScriptRuntime.toString(ScriptRuntime.java:761) at org.mozilla.javascript.ScriptRuntime.notFunctionError(ScriptRuntime.java:3774) at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThisHelper(ScriptRuntime. java:2269) at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime. java:2251) at org.mozilla.javascript.optimizer.OptRuntime.callProp0(OptRuntime.java:83) at org.mozilla.javascript.gen.script_5._c_evaluate_1(script:6) at org.mozilla.javascript.gen.script_5.call(script) at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:394) at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3091) at org.mozilla.javascript.gen.script_5.call(script)并且不知道从哪里去。当我不调用 addModifier 方法时,给定的代码工作,并在堆栈跟踪中给出错误 notFunctionError down认为Rhino没有将给定的方法解释为JavaScript函数。and don't know where to go from there. When I don't call addModifier method the given code works, and given the error notFunctionError down in the stack trace I think that Rhino doesn't interpret the given method as a JavaScript Function. OSX 10.8.2 Java 7 Rhino 1.7R4重现错误的完整Maven项目可以是发现此处Complete Maven project that reproduces the error can be found here推荐答案 tl; dr请参阅这些 两个替代方案。tl;dr see these two alternatives.上述方法的问题是 Target.prototype 未在脚本范围内正确设置。请参阅静态 ScriptableObject.defineClass() 方法,详细说明如何在脚本范围内正确定义原型。The problem with the approach above is that Target.prototype is not properly set up in the script scope. See the static ScriptableObject.defineClass() method for details on how to properly define prototypes in a script scope.你有一个为脚本提供 Target 构造函数的几种替代方法。 第一个替代方案是始终定义目标所有脚本的构造函数。如果您事先知道希望目标全局可用,则此方法很有效。这基本上归结为以下几点:You have a couple alternatives for providing the Target constructor to your scripts. The first alternative would be to always define the Target constructor for all scripts. This works well if you know ahead of time that you want Target to be globally available. This basically comes down to the following:final Context context = Context.enter();try { final ScriptableObject scope = context.initStandardObjects(); ScriptableObject.defineClass(scope, Target.class, false, true); context.evaluateString(scope, script, "script", 1, null); // etc.} finally { Context.exit();}如果您希望脚本作者决定哪些构造函数是必需的,第二种选择是提供 defineClass 脚本功能。使用此函数,脚本作者可以在其类路径上导入任何可编写脚本的对象(可能超出您想要的范围)。要向脚本提供 defineClass 函数,请在输入上下文后执行以下操作:If instead you want the script author to decide which constructors are necessary, the second alternative is to provide the defineClass function to scripts. With this function, script authors can "import" any scriptable objects on their class path (which may be more than you want to allow). To provide the defineClass functions to scripts, do the following after entering the context:final Context context = Context.enter();try { final ScriptableObject scope = context.initStandardObjects(); scope.defineFunctionProperties( new String[] {"defineClass"}, Global.class, ScriptableObject.DONTENUM); context.evaluateString(scope, script, "script", 1, null); // etc.} finally { Context.exit();}然后,JavaScript作者使用目标构造函数包含以下内容:And then, the JavaScript author makes use of the Target constructor with the following:defineClass("com.acme.rhino.Target");// whatever `getClassName()` returns is now availablevar target = new Target();在上述两个分支中,我做了一些其他更改,如果你做得更好,如果您向目标构造函数添加更多内容。零参数构造函数不需要 @JSConstructor 注释。如果你以后想要一个接受参数的构造函数,那么这个零参数构造函数将被用作原型构造函数,你可以在一个方法上使用 @JSConstructor 注释用于初始化您的对象。根据您编写此构造函数方法的方式,在JavaScript中使用 new 关键字非常重要。In both of the above branches, I've made a couple other changes that set you up better if you add more to the Target constructor. The zero argument constructor doesn't need the @JSConstructor annotation. If you later want to have a constructor that accepts arguments, this zero argument constructor will be used as the prototype constructor, and you can use the @JSConstructor annotation on a method that will be used to initialize your object. Depending on how you author this constructor method, it will become important to use the new keyword in your JavaScript.简而言之, Packages.com.acme ... 语法不对于访问 ScriptableObject 非常有用c $ c>来自脚本的构造函数。In short, the Packages.com.acme... syntax is not useful for getting access to ScriptableObject constructors from scripts. 这篇关于从JavaScript调用@JSFunction,TypeError:找不到对象的默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 08-22 19:15