Bizarre instanceof behaviour

S

Sean Inglis

Well bizarre to me, anyway.

I've distilled it down to two small files:


testtop.htm
===============================
<html>
<head>
<script language="Javascript">

var TOPTEST = [1,2,3];

alert('hellotop');
alert(TOPTEST instanceof Array);
</script>
</head>
<frameset rows="100%">
<frame src="testchild.htm">
</frameset>
</html>
===============================


and testchild.htm
===============================
<html>
<head>

<script language="Javascript">

function testtop() {
alert('hellochild');
alert(parent.TOPTEST);
alert((parent.TOPTEST) instanceof Array);
}

</script>
</head>
<body>
<h1>body</h1>
<input type="BUTTON" onclick="testtop();" value="test">
</body>
</html>
===============================


A few deprecated features aside, when I load testtop.htm, instanceof
array is true as I'd expect, but when I check this from the button in
testchild.htm, instanceof array is false.

I suspect I'm missing something obvious, as this behaviour is
consistent in IE 6.0, Opera 9.1 and Firefox 2.0.0.1 (all WIN32, I'll
check Linux when I get home).

Any pointers to what I'm missing, or can anyone shed any light on this
behaviour?

Thanks

Sean
 
M

Matt Kruse

Sean said:
A few deprecated features aside, when I load testtop.htm, instanceof
array is true as I'd expect, but when I check this from the button in
testchild.htm, instanceof array is false.

When the frameset document resolves "Array" it finds it defined in its
window object: window.Array.
The main document has its own window object, and its own version of
window.Array.

So, the main documents Array object isn't the same object as the frameset's
Array object, even though they are both instances of the same native object.

Instead of this:
alert((parent.TOPTEST) instanceof Array);

try this:
alert((parent.TOPTEST) instanceof parent.Array);

Or, if you just care that the object looks and acts like an Array, try
something like:

/**
* Return true if an object is not undefined
*/
function def(o) {
return typeof(o)!="undefined";
}
/**
* Try to figure out if an object can be treated like an Array - ie,
iterated over using numeric indexes
*/
function isArrayLike(o) {
if (o==null || typeof(o)!="object" || typeof(o.length)!="number") {
return false;
}
// Check to see if the object is an instance of the window's Array object
if (def(Array) && def(o.constructor) && o.constructor==Array) {
return true;
}
// It might be an array defined from another window object - check to see
if it has an Array's methods
if (typeof(o.join)=="function" && typeof(o.sort)=="function" &&
typeof(o.reverse)=="function") {
return true;
}
// As a last resort, let's see if index [0] is defined
return (o.length==0 || def(o[0]));
};
 
S

Sean Inglis

Matt said:
Sean said:
A few deprecated features aside, when I load testtop.htm, instanceof
array is true as I'd expect, but when I check this from the button in
testchild.htm, instanceof array is false.

When the frameset document resolves "Array" it finds it defined in its
window object: window.Array.
The main document has its own window object, and its own version of
window.Array.

So, the main documents Array object isn't the same object as the frameset's
Array object, even though they are both instances of the same native object.

Instead of this:
alert((parent.TOPTEST) instanceof Array);

try this:
alert((parent.TOPTEST) instanceof parent.Array);

Or, if you just care that the object looks and acts like an Array, try
something like:

/**
* Return true if an object is not undefined
*/
function def(o) {
return typeof(o)!="undefined";
}
/**
* Try to figure out if an object can be treated like an Array - ie,
iterated over using numeric indexes
*/
function isArrayLike(o) {
if (o==null || typeof(o)!="object" || typeof(o.length)!="number") {
return false;
}
// Check to see if the object is an instance of the window's Array object
if (def(Array) && def(o.constructor) && o.constructor==Array) {
return true;
}
// It might be an array defined from another window object - check to see
if it has an Array's methods
if (typeof(o.join)=="function" && typeof(o.sort)=="function" &&
typeof(o.reverse)=="function") {
return true;
}
// As a last resort, let's see if index [0] is defined
return (o.length==0 || def(o[0]));
};

Thanks Matt, annoying then, and counter-intuitive (AFAIC), but not
quite the show-stopper I thought it was.

This actually manifests itself in the version of json.js I'm using,
rather than in any of "my" code. I'll check the latest version and
report it as a problem if needed.

Sean
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top