Breaking instanceof in Javascript

That’s right, this afternoon I figured out how to break instanceof in Javascript. Since I don’t use it often, I figured it worked just like it does in PHP. Basically it does, with one major caveat. Mozilla’s javascript reference gives this definition of the instanceof operator:

Use instanceof when you need to confirm the type of an object at runtime. For example, when catching exceptions, you can branch to different exception-handling code depending on the type of exception thrown.

Earlier today, I was trying to pass data from a child window to its parent window. From there, the parent window used JSON to encode the data ….. but it never got encoded. Upon further investigation, I saw that JSON used the instanceof operator to determine if an object was an Array. I created these test pages to confirm my results:

parent.html

1
2
3
4
5
function foobar(value){
  alert(value instanceof Array);
  alert(value instanceof child_window.Array);
}
var child_window = window.open('child.html');

child.html

1
window.opener.foobar(new Array(1,2,3));

The first alert is false, while the second one is true.

In Javascript, all objects are “owned” at the root level by the window. Since the window is different for child windows, it makes sense that instanceof would break.

For most small applications, this doesn’t matter. But for Webmail, it does. I have a couple ideas for a good workaround, but nothing set in stone yet.

2 thoughts on “Breaking instanceof in Javascript

  1. (This is way after the fact, I know, but whatever.)

    You didn’t really “break” instanceof here, you just didn’t get the answer you were expecting. All instanceof really does is checks to see if the function on the right is equal to any of the the constructor functions in the prototype chain of the object on the left. That is to say, it asks “Was this constructor function over here used to create this object over here?” In the case of the first one, you were creating the new array within the child window and passing it to the parent window, where foobar() exists in the scope of the parent window. And so the first one is asking “Was this.Array() used to create value?” No, child_window.Array() was used to create it.

    Now if only I could find a way to test if an object is an instanceof Window in IE… :)

  2. Here’s another interesting thing with instanceof in JavaScript. Guess what the output of this is:

    var s = “hello”;
    alert(s instanceof String);

    Surprisingly, it is false! A srting literal isn’t a string in JavaScript. The following shows true:

    var s = new String(“hello”);
    alert(s instanceof String);

    Very annoying, especially if you’re a Java programmer… :-(

Comments are closed.