Subj : Re: Using JS_InstanceOf with jsval's To : Mike Gibson From : Brendan Eich Date : Tue Jan 20 2004 01:54 pm Mike Gibson wrote: >I'm having problems getting JS_InstanceOf to return what I expect when >I use jsval's returned from scripts. I create s simple object model >with the class "A" as the parent of "B". JS_InstanceOf then tells me >"new A();" is an instance of "B", which isn't correct. Am I using it >right? > >With the following JavaScript (test.js): > > function A() { this.a = 1; } > function B() { this.b = 2; } > B.prototype = new A; > >I run the following C++ code (standard init code snipped): > > // Compile and run the above JavaScript > ... snip ... > > char *s; > jsval aval, bval; > s = "a = new A();"; > ok = JS_EvaluateScript(cx, glob, s, strlen(s), "", 0, &aval); > s = "b = new B();"; > ok = JS_EvaluateScript(cx, glob, s, strlen(s), "", 0, &bval); > > // this JS_Instance call returns true when it should return false > JS_InstanceOf(cx, JSVAL_TO_OBJECT(aval), > JS_GetClass(JSVAL_TO_OBJECT(bval)), NULL)); > The JS_InstanceOf API is six+ old, so it predates the instanceof operator by several years and (in spite of the name) does something more than a little bit different. It is defined to return true if obj is an instance of the JSClass, and since user-defined constructors such as A and B all construct instances of the native Object class, the answer should be true here. Here is some JS shell session copy/paste: js> function A() { this.a = 1; } js> function B() { this.b = 2; } js> B.prototype = new A; [object Object] js> var a = new A js> var b = new B js> b instanceof A true js> b instanceof B true js> a instanceof A true js> a instanceof B false This shows correct behavior, per ECMA-262 Edition 3. If you want an API to tell what the instanceof operator's result would be, use this: JSObject *b = JSVAL_TO_OBJECT(bval); JSObject *B = JS_GetConstructor(cx, b); JSBool answer; JS_GET_CLASS(cx, B)->hasInstance(cx, B, JSVAL_TO_OBJECT(aval), &answer); I've left out error handling, as usual with these sorts of sketches. Sorry there isn't a JS_HasInstance API; also, sorry we can't rename JS_InstanceOf, but that's a cost of business with long-lived C APIs. /be .