4

Is it possible to make an Java object the prototype of a JavaScript object? Like the following:

var Person = Java.type("Person");
var hans = new Person();
hans.name = "Hans";

var employeeFactory = function() {
    var F = function(){};
    F.prototype = hans;
    return new F();
};

var fritz = employeeFactory();
print(fritz.name);

Here Person is a Java Bean. The variable hans is set as the instance of this Java class. The line hans.name = "Hans" sets the name field in the Java object as expected. But when the object fritz is created in the factory function, it doesn't get linked to the expected prototype. Is there any reason why the Java instance isn't accepted as prototype?

4
  • I'm really surprised that doesn't work. Commented Dec 28, 2014 at 10:15
  • Only tangentially related, but does Nashorn not support Object.create? Commented Dec 28, 2014 at 10:15
  • 1
    Interesting point. Not only does Nashorn know the Object.create function. If I use it instead of the factory, and try to create a JS-object with the Java instance as prototype, there is an error: TypeError: Person@73d4cc9e is not an Object. That's a real pitty. Would have been nice to inherit from Java beans. Commented Dec 28, 2014 at 19:22
  • That is a pity. I haven't read up on Nashorn much, unfortunately. I wonder what happens if you try it with Rhino. Commented Dec 29, 2014 at 8:02

1 Answer 1

4

It might work in Rhino, because in Rhino all beans are wrapped into JS native objects before being exposed to the JS program. Nashorn OTOH doesn't create wrappers. You can, however, use Nashorn's non-standard Object.bindProperties that adds properties from one object to another, bound to the original object's instance as its this. That's essentially as close as you can get (well, it's pretty darn close) to a wrapper. The exact specification is:

Object.bindProperties(dst, src)

creates bound properties from all properties in src object, puts them into the dst object, and returns the dst object. Since the properties are bound to src, dst.foo will delegate to src.foo for its value. bindProperties has been coded specifically so that it can handle ordinary Java objects as src.

With that in mind, I believe that if you change the line

F.prototype = hans;

to

F.prototype = Object.bindProperties({}, hans);

you'll get what you wanted. That would work with Object.create too, e.g. Object.create(Object.bindProperties({}, somePojo)).

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your response. I'm only interested in Nashorn though. But at least this gives me a hint of what goes "wrong" in Nashorn.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.