Why is comparing the “.constructor” property of tw

2019-06-06 06:12发布

问题:

I'm trying to understand why the following is not working as I would think it does. I'd like to check whether an object is a window. I was thinking that checking the constructors of the current window and another window would work.

So, first creating another window:

var popup = window.open('', '', '');

And then checking with:

popup.constructor === window.constructor;

But for some reason the results vary among browsers:

  • IE7: Returns true
    • But that's simply because .constructor === undefined
  • IE8: Returns false
  • IE9: Throws an error with no text ("")
  • Chrome: Returns false
    • Though in both cases .constructor === DOMWindow - but DOMWindow is not accessible directly like this
  • Opera: Returns false
    • Though in both cases .constructor === Object
  • Firefox: Returns false
    • Though in both cases .constructor === Window

Why isn't this reliable and working correctly? jQuery simply checks for "setInterval" in window, but I'd like to create a more robust function for checking whether an object is a window.

回答1:

Every separate window is a separate global context for the interpreter (and yes I'm ignoring IE7 for the moment). Your issue really becomes clear when you think about instanceof:

if (something instanceof Array) { ... }

The problems with that occur when "something" is a value that was constructed in a separate context, like an iframe for example. Each window has it's very own copy of the "Array" constructor, so even though an object may be an Array instance, it's not an instance of the same constructor function.

I suspect that the IE7 behavior is related to some other weirdness that I think is something like window.window being not equal to window. Like, one of them is in fact a reference to something internal. (Maybe it's window not being equal to window.self even though they otherwise behave identically. I don't invest a lot of philosophical thought time in contemplating IE7.)