+ // Instance Methods ////////////////////////////////////////////////////////////////////
+
+ public abstract Object get(Object key) throws JS.Exn;
+ public abstract void put(Object key, Object val) throws JS.Exn;
+ public abstract Object[] keys();
+
+ public Number coerceToNumber() { throw new Error("you cannot coerce a " + this.getClass().getName() + " into a Number"); }
+ public String coerceToString() { throw new Error("you cannot coerce a " + this.getClass().getName() + " into a String"); }
+ public boolean coerceToBoolean() { throw new Error("you cannot coerce a " + this.getClass().getName() + " into a Boolean"); }
+
+
+ // Inner Classes /////////////////////////////////////////////////////////////////////////
+
+ /** A sensible implementation of the abstract methods in the JS class */
+ public static class Obj extends JS {
+ private Hash entries = new Hash();
+ private boolean sealed = false;
+ public Obj() { this(false); }
+ public Obj(boolean sealed) { this.sealed = sealed; }
+ /** a sealed object cannot have its properties modified */
+ public void setSeal(boolean sealed) { this.sealed = sealed; }
+ public Object get(Object key) { return entries.get(key); }
+ public void put(Object key, Object val) { if (!sealed) entries.put(key, val); }
+ public Object[] keys() { return(entries.keys()); }
+ }
+
+ /** An exception which can be thrown and caught by JavaScript code */