var i = this.innerScripts.indexOf(script);
But I don't find if innerScripts is an array of jsdIScripts.
This however works:
if (i < 0)
{
for (var j = 0; j < this.innerScripts.length; j++)
{
if (script.tag == this.innerScripts[j].tag)
{
return this.innerScripts[j];
}
}
}
Now I am confused, shouldn't indexOf work?
John.
innerScripts is a JS Array, right? Where did it come from?
What exactly is |script| here?
> Now I am confused, shouldn't indexOf work?
Not if the actual objects don't test ==. I assume they don't, given your .tag test?
-Boris
sourceFile.innerScripts = [];
>
> What exactly is |script| here?
These come from jsdIStackFrame script field, they are jsdIScript objects.
>
>> Now I am confused, shouldn't indexOf work?
>
> Not if the actual objects don't test ==. I assume they don't, given
> your .tag test?
When (script.tag == this.innerScripts[j].tag) is true,
then (script == this.innerScripts[j]) is true but indexOf < 0 (in FF3pre).
>
> -Boris
Is |script === this.innerScripts[j]| in this case? It looks like that's what
indexOf actually uses as a test, now that I look at it.
-Boris
Note that this doesn't really answer my question; I want to know where the
entries come from too.
-Boris
indexOf doesn't know anything about .tag, it only knows strict
equality (===), per
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf#Description
.
If you want to find the entry, rather than the index, then you could
use filter with a predicate checking .tag:
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:filter
Mike
script === this.innerScripts[j] is false, so the problem is not indexOf.
The question then is why can't we compare two jsdIScript objects with ===?
>>> innerScripts is a JS Array, right? Where did it come from?
>>
>> sourceFile.innerScripts = [];
>Note that this doesn't really answer my question; I want to know where
>the entries come from too.
The entries come from jsdIDebuggerService
onScriptCreated: function(script)
The script objects are passed from a component into a window if that
matters.
Ok, so why don't jsdIScript objects compare with ===? Or how can I
predict when === and indexOf will work and will not work?
>
> If you want to find the entry, rather than the index, then you could
> use filter with a predicate checking .tag:
>
> http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:filter
>
> Mike
I know there are other ways to solve this problem but I want to
understand why indexOf does not work so I know in future whether to use it.
The precise answer to that in your case depends on where they come from. But in
brief, XPConnect will map the same underlying C++ nsISupports to multiple
XPCWrappedNatives if they are being wrapped in different scopes. The equality
hook for the class unwraps and compares the underlying pointers, but that's only
used for the == operator. === does strict JSObject identity (modulo the
inner/outer hack, iirc).
> The entries come from jsdIDebuggerService
> onScriptCreated: function(script)
> The script objects are passed from a component into a window if that
> matters.
Which means they're wrapped in the scope of the component, I would expect. I
assume that your jsdIStackFrame access to get the script you're calling indexOf
on happens somewhere outside that component?
-Boris
and, in this case, the JSObjects are actually wrappers around the
objects that I am reasoning about. Hence === fails.
Therefore, I can't count on any normal object comparisons. I won't be
able to figure out what kind of wrapper I have (there is no test for the
wrapper kind and they are created under circumstances I don't control or
even know about).
>
>> The entries come from jsdIDebuggerService
>> onScriptCreated: function(script)
>> The script objects are passed from a component into a window if that
>> matters.
>
> Which means they're wrapped in the scope of the component, I would
> expect. I assume that your jsdIStackFrame access to get the script
> you're calling indexOf on happens somewhere outside that component?
Yep. The array is filled on one code path and the test is made on
another. The XPConnect crossing can be, well, anywhere.
So, I need to approach this differently.
If you're reasoning about the C++ objects, yes. Clearly, some sort of wrapping
needs to happen to expose a C++ object to JS....
> I won't be able to figure out what kind of wrapper I have
You have an XPCWrappedNative. This is the way that C++ objects are exposed to
JS in Gecko.
> they are created under circumstances I don't control or
> even know about).
XPCWrappedNatives are created when a C++ object needs to be reflected into JS.
That said, your conclusion seems correct. You can't rely on === for JS
reflections of C++ objects unless all your code runs in a single scope.
-Boris
Sure about the first bit? I'm not after pondering
http://developer.mozilla.org/en/docs/XPConnect_wrappers
In addition to XPCWrappedNative there are other wrappers and wrapper
wrappers and soon the room was filling the wrappers. Or at least that's
how it comes across to me.
Yes.
> I'm not after pondering http://developer.mozilla.org/en/docs/XPConnect_wrappers
> In addition to XPCWrappedNative there are other wrappers and wrapper
> wrappers
Most of those have to do with either directly interacting with other scopes or
directly interacting with content DOMs. Doesn't sound like you're doing any of
that.
-Boris