Search code examples
javascriptjavanashorn

What is the use of overriding hasMember() inside JSObject, AbstractJSObject?


I understand that this helper method can be called from a Java code to check if your Java/JS Object has a property you are looking for but i would like to know if this is called by the Nashorn Engine while we use this JSObject/AbstractJSObject implementation in a JavaScript code.

I am aware of the fact that doing a . inside JavaScript will in turn invoke the Java method .getMember()


Solution

  • If "in" operator in used in JavaScript (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in) on a JSObject instance, Nashorn will call hasMember method on that JSObject.

    Example code:

    import javax.script.*;
    import jdk.nashorn.api.scripting.*;
    
    public class Main {
        public static void main(String[] args) throws Exception {
            ScriptEngineManager m = new ScriptEngineManager();
            ScriptEngine e = m.getEngineByName("nashorn");
            e.put("obj", new AbstractJSObject() {
                @Override
                public boolean hasMember(String name) {
                    System.out.println("hasMember called for " + name);
                    return false;
                }
            });
            // in operator triggers hasMember call on JSObject instance
            e.eval("if ('foo' in obj) print('yes')");
        }
    }
    

    The output from the above program looks like:

    hasMember called for foo