Я пытаюсь получить доступ к цепочке прототипов объекта Javascript через Nashorn. Несоответствие, которое я вижу, находится в цепочке прототипов класса против экземпляра класса. Кажется, что прототип Nashorn действителен только для объекта экземпляра, но не для самих классов.
Следующий код демонстрирует проблему:
import jdk.nashorn.api.scripting.NashornScriptEngine;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class Main {
private static String script =
"function MyClass() {" +
" this.nonProtoProp = 1;" +
"}" +
"MyClass.prototype.protoProp = 2;" +
"myClass = new MyClass();";
public static void main(String[] args) throws ScriptException {
NashornScriptEngine engine = (NashornScriptEngine) new ScriptEngineManager()
.getEngineByName("nashorn");
engine.eval(script);
ScriptObjectMirror som = (ScriptObjectMirror) engine.get("myClass");
String[] nonProtoKeys = som.getOwnKeys(true);
ScriptObjectMirror proto = (ScriptObjectMirror) som.getProto();
String[] protoKeys = proto.getOwnKeys(true);
System.out.println("Non-proto keys:");
for (String key : nonProtoKeys)
System.out.println("\t" + key);
System.out.println("Proto keys:");
for (String key : protoKeys)
System.out.println("\t" + key);
}
}
Здесь мы регистрируем цепочку прототипов экземпляра объекта myClass
. Мы видим nonProtoProp
в списке «Прото-ключи» и protoProp
в списке «Прото-ключи».
Однако, если вместо объекта MyClass
назначено som
, я вижу набор методов Javascript по умолчанию, таких как toString
и length
, но не отображаются из моих пользовательских свойств в любом списке. Я бы, конечно, ожидал, что nonProtoProp
будет отсутствовать, но почему protoProp
не отображается? Это не свойство какого-либо одного экземпляра, это свойство класса.
У меня нет самого сильного дескриптора концепции прототипа Javascript в целом, но этот пример действительно дает ожидаемые результаты, если выполняется в консоли Firefox (protoProp
появляется в цепочке прототипов MyClass
).
Примечание: я знаю, что nonProtoProp все еще находится в прототипе :) имя просто для того, чтобы отличить способ, которым они были назначены / созданы