2009-03-25 6 views
3

Quel est le meilleur moyen de renvoyer un objet hôte à JavaScript dans Rhino? J'ai deux classes comme ceci:Renvoyer un objet hôte dans Rhino

public class Hosted extends org.mozilla.javascript.ScriptableObject { 
    private static final long serialVersionUID = 1; 
    public Hosted() {} 
    public void jsConstructor() {} 

    public String getClassName() { 
     return "Hosted"; 
    } 

    public Member jsGet_member() { 
     Member m = new Member(); 
     m.defineFunctionProperties(new String[] { "toString" }, m.getClass(), DONTENUM); 
     return m; 
    } 
} 

public class Member extends org.mozilla.javascript.ScriptableObject { 
    private static final long serialVersionUID = 2; 
    public Member() {} 
    public void jsConstructor() {} 

    public String getClassName() { 
     return "Member"; 
    } 

    public String toString() { 
     return "called toString()"; 
    } 
} 

Il travaille, en ce sens que je peux appeler la méthode toString, mais l'objet membre ne se comporte pas comme j'attendre:

js> defineClass("Hosted"); 
js> defineClass("Member"); 
js> var h = new Hosted(); 
js> h.toString(); 
[object Hosted] 
js> h instanceof Hosted; 
true 
js> h.__proto__; 
[object Hosted] 
js> 
js> var m = h.member; 
js> m.toString(); 
called toString() 
js> m instanceof Member; // Should be true 
false 
js> m.__proto__; // Should be [object Member] 
null 

Si je appeler Object.prototype.toString cependant, il ne dit que c'est un objet membre:

js> Object.prototype.toString.call(m); 
[object Member] 

J'ai essayé d'appeler m.setPrototype et Context.javaToJS.

Répondre

4
public Scriptable jsGet_member() { 
     Scriptable scope = ScriptableObject.getTopLevelScope(this); 
     Member m = new Member(); 
     m.setParentScope(scope); 
     // defineClass("Member") must have previously been called. 
     m.setPrototype(ScriptableObject.getClassPrototype(scope, "Member")); 
     m.defineFunctionProperties(new String[] { "toString" }, 
       m.getClass(), DONTENUM); 
     return m; 
    } 

js> defineClass("Member") 
js> defineClass("Hosted") 
js> var h = new Hosted(); 
js> var m = h.member; 
js> m.toString(); 
called toString() 
js> m instanceof Member; 
true 
js> m.__proto__; 
[object Member] 

Modifier: La méthode peut aussi être écrit:

public Scriptable jsGet_member() { 
     Scriptable scope = ScriptableObject.getTopLevelScope(this); 
     Context cx = Context.getCurrentContext(); 
     Member m = (Member)cx.newObject(scope, "Member"); 
     m.defineFunctionProperties(new String[] { "toString" }, 
       m.getClass(), DONTENUM); 
     return m; 
    } 

qui appellera Member.jsConstructor; il peut y avoir d'autres différences aussi.

+0

Merci, c'est parfait. –

Questions connexes