我在项目中使用了nashorn。我想从json获取属性,但是属性可能没有值(value)。
在javascript中,如果property为null,则使用可选的链接并设置一个值;但是在nashorn中,当我使用(?。)时,出现以下错误:

import org.springframework.stereotype.Service
import javax.script.ScriptEngineManager
import javax.script.Bindings

@Service
class SampleService {

    class Person(
            val firstName: String,
            val lastName: String,
            val child: Child?
    )

    class Child(
            val name: String,
            val age: Int
    )

    fun runScript() {
        val engine = ScriptEngineManager().getEngineByName("nashorn")
        val bindings: Bindings = engine.createBindings()
        val person = Person("John", "Smite", null)
        bindings["person"] = person
        try {
            val script = """
               var childAge = person.child?.age ?? 0;
               childAge; //return as result.
            """.trimIndent()
            val scriptResult: Any = engine.eval(script, bindings)
        } catch (e: Exception) {
            throw e
        }

    }
}
我收到此错误:
javax.script.ScriptException: <eval>:1:28 Expected an operand but found .
var childAge = person.child?.age ?? 0;
^ in <eval> at line number 1 at column number 28
我检查了此链接,但无法解决问题:
Optional chaining (?.)
如何解决此错误?

最佳答案

Nashorn的当前策略是遵循ECMAScript规范。当我们使用JDK 8发行时,我们将与ECMAScript 5.1保持一致。 link
Nashorn引擎已作为JEP 335的一部分在JDK 11中弃用,并计划作为JEP 372的一部分从以后的JDK版本中删除。

可选链接非常新,并且ECMAScript 5.1不支持此功能。
我从 nashorn 迁移到 GraalVM JavaScript 并更改了代码,如下所示:

import com.oracle.truffle.js.scriptengine.GraalJSScriptEngine
import org.graalvm.polyglot.Context
import org.graalvm.polyglot.HostAccess
import org.springframework.stereotype.Service
import javax.script.ScriptEngine


@Service
class SampleService {

    data class Person(
            val firstName: String,
            val lastName: String,
            val child: Child?
    )

    data class Child(
            val name: String,
            val age: Int
    )

    fun runScript() {

        val person = Person("John", "Smite", null)

        val engine: ScriptEngine = GraalJSScriptEngine.create(null,
                Context.newBuilder("js")
                        .allowHostAccess(HostAccess.ALL)
                        .allowExperimentalOptions(true)
                        .option("js.ecmascript-version", "2020")
                        .option("js.nashorn-compat", "true"))
        engine.put("person", person)
        try {
            val script = """
                print(person.child?.name);
                //print undefined
                print(person.child?.name ?? 'not exist');
                //print not exist
            """.trimIndent()
            engine.eval(script)
        } catch (e: Exception) {
            throw e
        }
    }
}

关于javascript - nashorn中的可选链接(?。),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/64211977/

10-12 03:03