Closed Bug 475038 Opened 16 years ago Closed 16 years ago

instanceof Function returns "false" when sending an object from one window to another that contains a function.

Categories

(Core :: JavaScript Engine, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: alex.petrescu, Unassigned)

References

()

Details

(Whiteboard: [dupe me])

User-Agent:       Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.5) Gecko/2008120121 Firefox/3.0.5
Build Identifier: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.5) Gecko/2008120121 Firefox/3.0.5

If you create an object in one window (the parent) that contains some properties and a function, then open a popup and send the object to the popup.  Firefox reports the instanceOf Function in the popup of the function as "false", but in the parent as "true".

Link details the background and has a live demo.

Reproducible: Always

Steps to Reproduce:
1.Create JS object that has a function in it.
2.Open Popup
3.Send object to popup
4.Call instanceof Function on the function inside the object on the child window.
Actual Results:  
In Parent:
obj["myFunc"] instanceof Function == true
In Child:
obj["myFunc"] instanceof Function == false

Expected Results:  
In Parent:
obj["myFunc"] instanceof Function == true
In Child:
obj["myFunc"] instanceof Function == true

This bug seems to happen in all major browsers.  IE also has an issue with the typeof operator, but Firefox doesn't.
you're sending JSON effectively so this may be invalid. please attach a minimal testcase.
Assignee: nobody → general
Component: General → JavaScript Engine
Keywords: testcase-wanted
Product: Firefox → Core
QA Contact: general → general
Isn't the page I linked enough of a test case?  It is only a few lines of code and illustrates the problem perfectly.

Sending an object from one window to another sends JSON?  Can you even pass functions through JSON?  The functions do get sent over, but instanceof doesn't return the correct type.  Why does typeof return "function" but instanceof Function return false?

It is most certainly a bug and it is not the expected behavior.  If I send an object from one window to another, I expect it to act exactly as it did in the parent window.
It's not a bug, it's an unfortunate interaction between the definition of "instanceof" (chasing the prototype chain) and the fact that different windows need to have different Function.prototype objects.

  a instanceof b

 means

  does a have on its prototype chain anywhere the object b.prototype?

This is a dup of something, but I'll WONTFIX it for now because to repair it would put us in violation of ECMA, as well as the necessary multi-global semantics of the web.
Status: UNCONFIRMED → RESOLVED
Closed: 16 years ago
Resolution: --- → WONTFIX
Whiteboard: [dupe me]
So wait, myFunc is a function in Window A, and you pass it to Window B and its no longer a function???

How is that anything but a bug?

myFunc instanceof Function should return "true" no matter what window it's in or who created it initially.

typeof myFunc returns "function" for both, so why wouldn't instanceof Function?  Why should where the function originated matter for typing?
Status: RESOLVED → UNCONFIRMED
Resolution: WONTFIX → ---
instanceof is not a "type" check, it's a check for delegation to prototype.  See http://bclary.com/2004/11/07/#a-11.8.6 and http://bclary.com/2004/11/07/#a-15.3.5.3 .

windowA.Function != windowB.Function (they're not the same object, which is important so that windowA changing its Function object doesn't pollute windowB).  Similarly with windowA.Function.prototype and windowB.Function.prototype.

You are asking if a function created in windowA has windowB.Function.prototype in its delegation (prototype) chain.  It does not, because when a function is created in windowA it is created linked to windowA's Function.

Compare:

myFunc instanceof opener.Function
Status: UNCONFIRMED → RESOLVED
Closed: 16 years ago16 years ago
Resolution: --- → WONTFIX
Alex, you are barking up the wrong tree. The ECMA-262 spec is clear and we are not going to break it, and probably real web content, by making up some hack.

Any reason for not using typeof?

The place to discuss fixing the ECMA-262 standard is the es-discuss@mozilla.org list. See https://mail.mozilla.org/listinfo/es-discuss for how to join and read the archive. And don't reopen this bug.

/be
I see the problem, I just don't think its the correct behavior.  You're basically saying you cannot ever use "instanceof" because as soon as an object its passed across a window boundary, all checks of "instanceof" will return false.

So either fix "instanceof" or get rid of it.  It doesn't make sense... if Window A has an object named "Blue" and window B has an object named "Blue", if I pass an instance of the object from one window to another, the expected behavior is that obj instanceof Blue == true in both Window's.  

The current behavior makes all code break since it's not a known issue that "instanceof Function" will not return true if the object has come across the boundary.  For that matter, instanceof any object will return false.

I read the ECMA standard that was posted and here's what it says:
The instanceof operator 
The production Relational Expression: Relational Expression instanceof Shift Expression is evaluated 
as follows: 
1. Evaluate Relational Expression. 
2. Call Get Value(Result (1)). 
3. Evaluate Shift Expression. 
4. Call Get Value(Result (3)). 
5. If Result (4) is not an object, throw a TypeError exception. 
6. If Result (4) does not have a [[HasInstance]] method, throw a TypeError exception. 
7. Call the [[HasInstance]] method of Result (4) with parameter Result (2). 
8. Return Result (7). 

So based on that pseudocode, Firefox works correctly, however, that doesn't take into account that WindowA.Function != WindowB.Function even though every developer expects it to be.

I think a fix would be that any time an object or function gets passed from one window to another, it would recreate the prototype chain as it exists in the parent window.

Then the expected behavior WindowA: myFunc instanceof Function == WindowB: myFunc instanceof Function.

As it stand, you can never use another Javascript library because if it uses "instanceof" it will act inconsistently if you have an application with multiple window.
Why are you still here? If you must vent, then at least vent to the es-discuss mailing list, where you might have a good effect. All you're doing here is ticking people off.

The idea of automatically changing prototype chains when objects cross global boundaries is nuts, in a word. It is unsound, incompatible (people decorate prototypes), insecure, and ineffecient, in more words. It's not going to happen.

Clue: Ajax libraries the world over, used at major sites, all use instanceof (and typeof, repeated clue) just fine. No one "can never use another [JS] library."

Stop spamming this bug.

/be
To take a more sympathetic tone and repeat my encouragement to bring this up on the es-discuss@mozilla.org list:

ES4, now withdrawn, did have an "is" operator that was supposed to work for built-in types such as Function in the way you want. There's real call for this, moreso for Array than for Function (since typeof returns "function" but not "array"). This "is" operator has not been proposed for the post-ES3.1 "Harmony" language. Something like it could be, with enough thought -- possibly shared thoughts and discussion on es-discuss -- but not here.

/be
How about doing some research first, and posting a relevant response, instead of flaming next time.  I was not venting, it was an issue I was actually running into, and frankly I wanted a solution not a "can't do anything, go away, you must be the only person in the world with this issue".

I was using the typeof, but that is broken across the window boundary as well in Internet Explorer (what the original bug was about on my page), so I tried some different approaches and that's how I ran across this issue.

As of now, there's no reliable cross-browser way of using built-in javascript operators to figure out whether a variable is truly a function.  Which sucks for trying to serialize JS objects and send them to Flash (what the original issue was).

Thanks for providing the info about ES4 and Harmony.

And FYI... Major AJAX libraries (such as JQuery) are having issues with this, and are breaking sites:
http://thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
(In reply to comment #10)
> How about doing some research first,

You first.

Your proposal of mutating prototype chains in objects passed across window boundaries shows lack of research, or really, lack of fundamental knowledge.

Anyway, it's hard to see how I should do more research, since I know more than a little about JS (since 1995; instanceof was after my time in standardization).

> and posting a relevant response

No, this is not a forum or newsgroup. You're out of line.

> instead
> of flaming next time.

Don't flame first, and in the wrong place.

> I was not venting, it was an issue I was actually
> running into, and frankly I wanted a solution not a "can't do anything, go
> away, you must be the only person in the world with this issue".

Which no one said. I explicitly recommended and encouraged you to take it to the es-discuss list. I meant it.

> I was using the typeof, but that is broken across the window boundary as well
> in Internet Explorer (what the original bug was about on my page), so I tried
> some different approaches and that's how I ran across this issue.

Then work around in IE some other way. There are lots of workarounds.

> As of now, there's no reliable cross-browser way of using built-in javascript
> operators to figure out whether a variable is truly a function.

And how would Mozilla hacking a non-standard extension help this problem?

Again, es-discuss.

> Which sucks
> for trying to serialize JS objects and send them to Flash (what the original
> issue was).

Work around.

> Thanks for providing the info about ES4 and Harmony.

I'm leery of your bad attitude, but: you're welcome.

> And FYI... Major AJAX libraries (such as JQuery) are having issues with this,
> and are breaking sites:
> http://thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/

John Resig has already been cc'ed.

Again, instanceof was added in the 3rd Edition, in 1999. The time to get that fixed has passed. The best use of effort here is fixing the next major version of the spec. We don't need more bugs like the IE one, or intentional browser-specific deviations from the spec.

/be
You need to log in before you can comment on or make changes to this bug.