微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

nashorn中的可选链接?

如何解决nashorn中的可选链接?

我在项目中使用了nashorn。我想从json获取属性,但属性可能没有价值。

在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版本中删除。

GraalVM JavaScript 可以代替以前在Nashorn引擎上执行的代码。它提供了所有 Nashorn以前提供的功能,许多功能可以通过 默认情况下,有些后面带有标志,有些则需要对您的 源代码。link

可选链接是相当新的功能,此功能不支持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
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。