<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: isArray: Why is it so bloody hard to get right?</title>
	<atom:link href="http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/feed" rel="self" type="application/rss+xml" />
	<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right</link>
	<description>Cleaning up the web with Ajax</description>
	<lastBuildDate>Thu, 17 May 2012 07:43:39 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
	<item>
		<title>By: sekostar</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-273809</link>
		<dc:creator>sekostar</dc:creator>
		<pubDate>Tue, 09 Jun 2009 14:33:28 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-273809</guid>
		<description>Sorry this is even simpler

&lt;code&gt;
function isArray(array){
    return array? !!array.push : false;
}
&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>Sorry this is even simpler</p>
<p><code><br />
function isArray(array){<br />
    return array? !!array.push : false;<br />
}<br />
</code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: sekostar</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-273808</link>
		<dc:creator>sekostar</dc:creator>
		<pubDate>Tue, 09 Jun 2009 14:20:38 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-273808</guid>
		<description>This is the simplest and easiest way I can think of:

&lt;code&gt;
 function isArray(array){
    try{ return !!array.push; }catch(e){ return false; }
 }
&lt;/code&gt;

I&#039;ve tested this and it works fine as far as I see.</description>
		<content:encoded><![CDATA[<p>This is the simplest and easiest way I can think of:</p>
<p><code><br />
 function isArray(array){<br />
    try{ return !!array.push; }catch(e){ return false; }<br />
 }<br />
</code></p>
<p>I&#8217;ve tested this and it works fine as far as I see.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: mjuhl</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270841</link>
		<dc:creator>mjuhl</dc:creator>
		<pubDate>Thu, 29 Jan 2009 04:18:21 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270841</guid>
		<description>@LeaVerou: Thanks, I was really just being facetious though.  On a more serious note, why not do it this way:
 
function isArray(object) {
  if (object instanceof Array) return true;
  return Object.prototype.toString.call(object) === &#039;[object Array]&#039;;
}
 
That way you&#039;re covering your bases pretty well.</description>
		<content:encoded><![CDATA[<p>@LeaVerou: Thanks, I was really just being facetious though.  On a more serious note, why not do it this way:</p>
<p>function isArray(object) {<br />
  if (object instanceof Array) return true;<br />
  return Object.prototype.toString.call(object) === &#8216;[object Array]&#8216;;<br />
}</p>
<p>That way you&#8217;re covering your bases pretty well.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: JasonP</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270589</link>
		<dc:creator>JasonP</dc:creator>
		<pubDate>Tue, 20 Jan 2009 02:09:49 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270589</guid>
		<description>here is my idea for an isArray function that is relatively speedy and detects Arrays, Subclassed Arrays and Arrays in separate frames. 

@kangax: There is a problem with using Array.prototype.toString.call(obj) with arrays with several items i.e. 1000 with firefox 3.x running it over 50000 iterations is unacceptably slow i.e. 15-20 secs.

The idea is sound but toString is the wrong function to use. I did some experimenting and I came up with this function drawing from several other peoples Ideas.

function isArray(obj) {
				if (obj instanceof Array) {
					return true;
				} else {						
					try {
						if (obj.length &gt; 0 &amp;&amp; Array.prototype.slice.call(obj,0,1)[0] === obj[0]) {
							return true;
						} else { 
							if (Array.prototype.slice.call(obj,0,1).length === obj.length) { 
								return true;
							}
						}						
					}catch (e) {}
					return false;					
				}
			}

This function is lightning fast for regular arrays or sub classed arrays on pages without frames as it is just a obj instance of Array call. For pages with frames it is a single call to Array.prototype.splice.call(obj,0,1) which is quick regardless of array length if the array has elements it makes sure the element it received is equal to the first item in the array, if it is an empty array it compares the length of Array.prototype.splice.call(obj,0,1) with the original obj.length both of which should be zero. 

for 50000 iterations  the timing was 
instanceof: 19ms
isarrayRegularArray: 48ms
isarrayFrameArray: 245ms

So for objects that are instances of Array according to Javascript the function call is approximately 2.5 times slower than the builtin instanceof command. for arrays in separate frames it is approximately 12-13 times slower. most importantly Array size is also not a contributing factor ran the tests with a 1000 element array and a 10000 element array with no time difference.</description>
		<content:encoded><![CDATA[<p>here is my idea for an isArray function that is relatively speedy and detects Arrays, Subclassed Arrays and Arrays in separate frames. </p>
<p>@kangax: There is a problem with using Array.prototype.toString.call(obj) with arrays with several items i.e. 1000 with firefox 3.x running it over 50000 iterations is unacceptably slow i.e. 15-20 secs.</p>
<p>The idea is sound but toString is the wrong function to use. I did some experimenting and I came up with this function drawing from several other peoples Ideas.</p>
<p>function isArray(obj) {<br />
				if (obj instanceof Array) {<br />
					return true;<br />
				} else {<br />
					try {<br />
						if (obj.length &gt; 0 &amp;&amp; Array.prototype.slice.call(obj,0,1)[0] === obj[0]) {<br />
							return true;<br />
						} else {<br />
							if (Array.prototype.slice.call(obj,0,1).length === obj.length) {<br />
								return true;<br />
							}<br />
						}<br />
					}catch (e) {}<br />
					return false;<br />
				}<br />
			}</p>
<p>This function is lightning fast for regular arrays or sub classed arrays on pages without frames as it is just a obj instance of Array call. For pages with frames it is a single call to Array.prototype.splice.call(obj,0,1) which is quick regardless of array length if the array has elements it makes sure the element it received is equal to the first item in the array, if it is an empty array it compares the length of Array.prototype.splice.call(obj,0,1) with the original obj.length both of which should be zero. </p>
<p>for 50000 iterations  the timing was<br />
instanceof: 19ms<br />
isarrayRegularArray: 48ms<br />
isarrayFrameArray: 245ms</p>
<p>So for objects that are instances of Array according to Javascript the function call is approximately 2.5 times slower than the builtin instanceof command. for arrays in separate frames it is approximately 12-13 times slower. most importantly Array size is also not a contributing factor ran the tests with a 1000 element array and a 10000 element array with no time difference.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: LeaVerou</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270570</link>
		<dc:creator>LeaVerou</dc:creator>
		<pubDate>Mon, 19 Jan 2009 17:31:03 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270570</guid>
		<description>@kangax: I was more concerned about the speed, rather than the subclassed arrays issue (which I consider quite trivial). Tests like Slickspeed aren&#039;t very forgiving, and punish you for even such small differences.
After doing more tests like the above, I noticed that the difference in speed is not always as dramatic, but the best result I got was still 2 times slower than the instanceof method. I&#039;m still undecided between &quot;fast and correct most of the time&quot; and &quot;slower but always correct&quot;. I guess I&#039;ll end up with the toString() method after all, but I can&#039;t decide now.

@mjuhl: This suffers from the same issues as the instanceof method and additionally its more obtrusive, since it adds an extra useless property to the Array prototype. Also, the ternary operator is redundant (return !!(o &amp;&amp; o.isArray); would suffice), and so is the conversion to boolean (since __isArray__ is already boolean).</description>
		<content:encoded><![CDATA[<p>@kangax: I was more concerned about the speed, rather than the subclassed arrays issue (which I consider quite trivial). Tests like Slickspeed aren&#8217;t very forgiving, and punish you for even such small differences.<br />
After doing more tests like the above, I noticed that the difference in speed is not always as dramatic, but the best result I got was still 2 times slower than the instanceof method. I&#8217;m still undecided between &#8220;fast and correct most of the time&#8221; and &#8220;slower but always correct&#8221;. I guess I&#8217;ll end up with the toString() method after all, but I can&#8217;t decide now.</p>
<p>@mjuhl: This suffers from the same issues as the instanceof method and additionally its more obtrusive, since it adds an extra useless property to the Array prototype. Also, the ternary operator is redundant (return !!(o &amp;&amp; o.isArray); would suffice), and so is the conversion to boolean (since __isArray__ is already boolean).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: mjuhl</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270502</link>
		<dc:creator>mjuhl</dc:creator>
		<pubDate>Thu, 15 Jan 2009 22:13:41 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270502</guid>
		<description>How about this??

Array.prototype.__isArray__ = true;
function isArray(o) {
	return (o &amp;&amp; o.__isArray__) ? !!o.__isArray__ : false;
};

alert(isArray([])+ &#039;,&#039; + isArray({})+ &#039;,&#039; + isArray(null));
// true,false,false</description>
		<content:encoded><![CDATA[<p>How about this??</p>
<p>Array.prototype.__isArray__ = true;<br />
function isArray(o) {<br />
	return (o &amp;&amp; o.__isArray__) ? !!o.__isArray__ : false;<br />
};</p>
<p>alert(isArray([])+ &#8216;,&#8217; + isArray({})+ &#8216;,&#8217; + isArray(null));<br />
// true,false,false</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: kangax</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270416</link>
		<dc:creator>kangax</dc:creator>
		<pubDate>Tue, 13 Jan 2009 22:47:32 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270416</guid>
		<description>@LeaVerou

Interesting. My results are actually less dramatic (FF3.0.5 on Mac OSX) and seem to be negligible even under `50000` iterations. The difference is still there, of course.

&lt;code&gt;
var arr = [1, &#039;a&#039;, /foo/, NaN];
var LIM = 50000;

console.time(&#039;instanceof&#039;);
for (var i=0; i&lt;LIM; i++) { arr instanceof Array; }
console.timeEnd(&#039;instanceof&#039;);

console.time(&#039;constructor&#039;);
for (var i=0; i&lt;LIM; i++) { arr.constructor == Array; }
console.timeEnd(&#039;constructor&#039;);

console.time(&#039;[[Class]]&#039;);
for (var i=0; i&lt;LIM; i++) { Object.prototype.toString.call(arr) == &#039;[object Array]&#039; }
console.timeEnd(&#039;[[Class]]&#039;);

instanceof: 86ms
constructor: 108ms
[[Class]]: 131ms
&lt;/code&gt;

Regarding &quot;sub-arrays&quot;, it should be trivial to special-case `isArray` to account for them. E.g.:

&lt;code&gt;
function Sub(){};
Sub.prototype = new Array();
var sub = new Sub();
sub instanceof Array; // true

function isArray(o) {
  return Object.prototype.toString.call(
    // to prevent constructor-less host objects from blowing up
    o.constructor ? o.constructor.prototype : o);
};

isArray(sub);
&lt;/code&gt;

You could of course change it to account for arbitrary-level &quot;sub-arrays&quot; (i.e. check up the prototype chain till reaching `null`)
I agree that this &quot;workaround&quot; is not &quot;ideal&quot;. Unfortunately, so is our current state of JS/DOM affairs : )</description>
		<content:encoded><![CDATA[<p>@LeaVerou</p>
<p>Interesting. My results are actually less dramatic (FF3.0.5 on Mac OSX) and seem to be negligible even under `50000` iterations. The difference is still there, of course.</p>
<p><code><br />
var arr = [1, 'a', /foo/, NaN];<br />
var LIM = 50000;</p>
<p>console.time('instanceof');<br />
for (var i=0; i&lt;LIM; i++) { arr instanceof Array; }<br />
console.timeEnd('instanceof');</p>
<p>console.time('constructor');<br />
for (var i=0; i&lt;LIM; i++) { arr.constructor == Array; }<br />
console.timeEnd('constructor');</p>
<p>console.time('[[Class]]');<br />
for (var i=0; i&lt;LIM; i++) { Object.prototype.toString.call(arr) == '[object Array]' }<br />
console.timeEnd('[[Class]]');</p>
<p>instanceof: 86ms<br />
constructor: 108ms<br />
[[Class]]: 131ms<br />
</code></p>
<p>Regarding &#8220;sub-arrays&#8221;, it should be trivial to special-case `isArray` to account for them. E.g.:</p>
<p><code><br />
function Sub(){};<br />
Sub.prototype = new Array();<br />
var sub = new Sub();<br />
sub instanceof Array; // true</p>
<p>function isArray(o) {<br />
  return Object.prototype.toString.call(<br />
    // to prevent constructor-less host objects from blowing up<br />
    o.constructor ? o.constructor.prototype : o);<br />
};</p>
<p>isArray(sub);<br />
</code></p>
<p>You could of course change it to account for arbitrary-level &#8220;sub-arrays&#8221; (i.e. check up the prototype chain till reaching `null`)<br />
I agree that this &#8220;workaround&#8221; is not &#8220;ideal&#8221;. Unfortunately, so is our current state of JS/DOM affairs : )</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: kangax</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270413</link>
		<dc:creator>kangax</dc:creator>
		<pubDate>Tue, 13 Jan 2009 22:29:55 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270413</guid>
		<description>@Jordan1

AFAIK, `Object.prototype.toString` is generic. In case of &quot;emergency&quot;, it is possible to &quot;restore&quot; it from the &quot;clean&quot; context of newly created frame (in clients which support frame creation/inspection):

&lt;code&gt;
Object.prototype.toString = (function(){
  var root = (document.body &#124;&#124; document.documentElement);
  var el = document.createElement(&#039;iframe&#039;);
  root.appendChild(el);
  var s = window.frames[window.frames.length-1].Object.prototype.toString;
  root.removeChild(el);
  return s;
})();
&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>@Jordan1</p>
<p>AFAIK, `Object.prototype.toString` is generic. In case of &#8220;emergency&#8221;, it is possible to &#8220;restore&#8221; it from the &#8220;clean&#8221; context of newly created frame (in clients which support frame creation/inspection):</p>
<p><code><br />
Object.prototype.toString = (function(){<br />
  var root = (document.body || document.documentElement);<br />
  var el = document.createElement('iframe');<br />
  root.appendChild(el);<br />
  var s = window.frames[window.frames.length-1].Object.prototype.toString;<br />
  root.removeChild(el);<br />
  return s;<br />
})();<br />
</code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: LeaVerou</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270407</link>
		<dc:creator>LeaVerou</dc:creator>
		<pubDate>Tue, 13 Jan 2009 19:17:15 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270407</guid>
		<description>Brilliant as an idea. The only problem that I see is that it&#039;s quite slower:
&lt;code&gt;
&gt;&gt;&gt; test = []
[]
&gt;&gt;&gt; debug.benchmark(util.isArray,[test],null,200000)
The function took 0.00104ms to execute and returned true
&gt;&gt;&gt; isArr2 = function(val) { return Object.prototype.toString.call(val) == &#039;[object Array]&#039;; }
function()
&gt;&gt;&gt; debug.benchmark(isArr2,[test],null,200000)
The function took 0.002125ms to execute and returned true
&lt;/code&gt;

Ok not slow as a function in general, but 20 times slower compared to the instanceof way. 

Perhaps a solution would be to check the length of window.frames and choose the method according to that, but then we&#039;d still face issues with:
1. Scripted new windows. 
2. Sublclassed arrays. I find it ok that the new method returns false for them, but it should be consistent. It should return either always true, or always false for subclassed arrays. It can&#039;t return true for them and if you add a frame suddenly false for them, or true if the suclassed array belongs to the current window and false if it belongs to a frame!

Combining both methods with the &#124;&#124; operator also suffers from problem 2, and would be even slower when the object is NOT an array. 

A method like isArray should be lightning fast since it&#039;s used very often. So even though I admire the brilliance of this solution, I&#039;m still uncertain whether to use it.</description>
		<content:encoded><![CDATA[<p>Brilliant as an idea. The only problem that I see is that it&#8217;s quite slower:<br />
<code><br />
&gt;&gt;&gt; test = []<br />
[]<br />
&gt;&gt;&gt; debug.benchmark(util.isArray,[test],null,200000)<br />
The function took 0.00104ms to execute and returned true<br />
&gt;&gt;&gt; isArr2 = function(val) { return Object.prototype.toString.call(val) == '[object Array]'; }<br />
function()<br />
&gt;&gt;&gt; debug.benchmark(isArr2,[test],null,200000)<br />
The function took 0.002125ms to execute and returned true<br />
</code></p>
<p>Ok not slow as a function in general, but 20 times slower compared to the instanceof way. </p>
<p>Perhaps a solution would be to check the length of window.frames and choose the method according to that, but then we&#8217;d still face issues with:<br />
1. Scripted new windows.<br />
2. Sublclassed arrays. I find it ok that the new method returns false for them, but it should be consistent. It should return either always true, or always false for subclassed arrays. It can&#8217;t return true for them and if you add a frame suddenly false for them, or true if the suclassed array belongs to the current window and false if it belongs to a frame!</p>
<p>Combining both methods with the || operator also suffers from problem 2, and would be even slower when the object is NOT an array. </p>
<p>A method like isArray should be lightning fast since it&#8217;s used very often. So even though I admire the brilliance of this solution, I&#8217;m still uncertain whether to use it.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: WebReflection</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270396</link>
		<dc:creator>WebReflection</dc:creator>
		<pubDate>Tue, 13 Jan 2009 12:45:04 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270396</guid>
		<description>if you define const NativeString = Object.prototype.toString; as first line of your application at least some recent browser will be secure enough ;-)</description>
		<content:encoded><![CDATA[<p>if you define const NativeString = Object.prototype.toString; as first line of your application at least some recent browser will be secure enough ;-)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: BenGerrissen</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270394</link>
		<dc:creator>BenGerrissen</dc:creator>
		<pubDate>Tue, 13 Jan 2009 11:10:07 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270394</guid>
		<description>Well.. if anyone extends Object.prototype, this technique not working is the last of his or her problems. Microwave Ovens will kill your beloved pets if you use them to dry their fur, so you can call those insecure, though if you read the manual, you would&#039;ve known it would kill your cat.</description>
		<content:encoded><![CDATA[<p>Well.. if anyone extends Object.prototype, this technique not working is the last of his or her problems. Microwave Ovens will kill your beloved pets if you use them to dry their fur, so you can call those insecure, though if you read the manual, you would&#8217;ve known it would kill your cat.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jordan1</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270393</link>
		<dc:creator>Jordan1</dc:creator>
		<pubDate>Tue, 13 Jan 2009 08:49:11 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270393</guid>
		<description>I bet sooner or later someone&#039;s going to come along and say that this technique is not secure because &quot;Object.prototype.toString&quot; can be overridden.</description>
		<content:encoded><![CDATA[<p>I bet sooner or later someone&#8217;s going to come along and say that this technique is not secure because &#8220;Object.prototype.toString&#8221; can be overridden.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: WebReflection</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270371</link>
		<dc:creator>WebReflection</dc:creator>
		<pubDate>Mon, 12 Jan 2009 16:40:54 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270371</guid>
		<description>nice one kangax, I was joking but your one seems to make sense :D

(end even if I prefere this one, I am sure performances are not the same of the other toString trick)</description>
		<content:encoded><![CDATA[<p>nice one kangax, I was joking but your one seems to make sense :D</p>
<p>(end even if I prefere this one, I am sure performances are not the same of the other toString trick)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: kangax</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270370</link>
		<dc:creator>kangax</dc:creator>
		<pubDate>Mon, 12 Jan 2009 15:41:15 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270370</guid>
		<description>@WebReflection

There&#039;s an easier way, really : )

function isArray(o) {
  try {
    Array.prototype.toString.call(o);
    return true;
  } catch(e) { }
  return false;
};
isArray([]); //true
isArray(); // false

See http://github.com/kangax/protolicious/tree/master/object.extensions.js#L1 for explanation</description>
		<content:encoded><![CDATA[<p>@WebReflection</p>
<p>There&#8217;s an easier way, really : )</p>
<p>function isArray(o) {<br />
  try {<br />
    Array.prototype.toString.call(o);<br />
    return true;<br />
  } catch(e) { }<br />
  return false;<br />
};<br />
isArray([]); //true<br />
isArray(); // false</p>
<p>See <a href="http://github.com/kangax/protolicious/tree/master/object.extensions.js#L1" rel="nofollow">http://github.com/kangax/protolicious/tree/master/object.extensions.js#L1</a> for explanation</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: kangax</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270369</link>
		<dc:creator>kangax</dc:creator>
		<pubDate>Mon, 12 Jan 2009 15:34:30 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270369</guid>
		<description>@kriszyp
Yes, indeed; I don&#039;t see a reason not to use `instanceof` in &quot;single-frame&quot; applications. 

The main downside I see in retrieving [[Class]] value is that we don&#039;t know how host objects implement it. They could be designed to throw error when [[Class]] lookup occurs (just like IE is known to throw for internal [[Get]] of certain objects - notably AcitveX components), or even collide with spec-defined values for native objects - &quot;Array&quot;, &quot;Function&quot;, etc. We can either do extensive testing or just deal with the fact that host objects&#039; behavior can never be relied upon.</description>
		<content:encoded><![CDATA[<p>@kriszyp<br />
Yes, indeed; I don&#8217;t see a reason not to use `instanceof` in &#8220;single-frame&#8221; applications. </p>
<p>The main downside I see in retrieving [[Class]] value is that we don&#8217;t know how host objects implement it. They could be designed to throw error when [[Class]] lookup occurs (just like IE is known to throw for internal [[Get]] of certain objects &#8211; notably AcitveX components), or even collide with spec-defined values for native objects &#8211; &#8220;Array&#8221;, &#8220;Function&#8221;, etc. We can either do extensive testing or just deal with the fact that host objects&#8217; behavior can never be relied upon.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: WebReflection</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270367</link>
		<dc:creator>WebReflection</dc:creator>
		<pubDate>Mon, 12 Jan 2009 14:50:21 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270367</guid>
		<description>P.S. ... what about this? ... lol!

function isArray(Object){
    var result = false;
    try{new Object.constructor(Math.pow(2, 32))}catch(e){result=/Array/.test(e.message)};
    return result;
};

alert(isArray([]));</description>
		<content:encoded><![CDATA[<p>P.S. &#8230; what about this? &#8230; lol!</p>
<p>function isArray(Object){<br />
    var result = false;<br />
    try{new Object.constructor(Math.pow(2, 32))}catch(e){result=/Array/.test(e.message)};<br />
    return result;<br />
};</p>
<p>alert(isArray([]));</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: kriszyp</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270364</link>
		<dc:creator>kriszyp</dc:creator>
		<pubDate>Mon, 12 Jan 2009 14:00:23 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270364</guid>
		<description>As WebReflection pointed out, this technique has it&#039;s own issues. If you are in a single frame or not sharing arrays between frames, it is actually really better and safer to use instanceof Array (where there is only one Array constructor) and avoid a library isArray or this toString based check. Since it is difficult for a framework to know what the context is, the library abstraction can be counter-productive except to help with cross-frame array sharing.</description>
		<content:encoded><![CDATA[<p>As WebReflection pointed out, this technique has it&#8217;s own issues. If you are in a single frame or not sharing arrays between frames, it is actually really better and safer to use instanceof Array (where there is only one Array constructor) and avoid a library isArray or this toString based check. Since it is difficult for a framework to know what the context is, the library abstraction can be counter-productive except to help with cross-frame array sharing.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: WebReflection</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270363</link>
		<dc:creator>WebReflection</dc:creator>
		<pubDate>Mon, 12 Jan 2009 13:58:37 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270363</guid>
		<description>@kangax, more than inherited I hoped it was searched into the proto. the Stack constructor is a prototype = [] and each instance an instanceof Array. Btw, I was not expecting an [object Array] on a primitive call with Object.prototype.toString and my comment was only to underline that is not 100% reliable and all this stuff means that the &quot;war about our own Array prototypes&quot; won&#039;t stop until JS2
I am still up for &lt;a href=&quot;http://www.3site.eu/JSL/&quot; rel=&quot;nofollow&quot;&gt;JSL&lt;/a&gt; ( JavaScript Standard Library ... that I could probably update removing IE 5 and 5.5 fixes ) to normalize up to JS 1.6 or greater the Array prototype ( forEach instead of every different each, for example ) but I am sure somebody will find a perfect way to recognize an array before every library will implement standard behaviours ( or, even better, why don&#039;t we agree about a single un-official method to retreive an array, like a toArray prototype that will return this if it is an array, slice.call(this, 0) in every other case )</description>
		<content:encoded><![CDATA[<p>@kangax, more than inherited I hoped it was searched into the proto. the Stack constructor is a prototype = [] and each instance an instanceof Array. Btw, I was not expecting an [object Array] on a primitive call with Object.prototype.toString and my comment was only to underline that is not 100% reliable and all this stuff means that the &#8220;war about our own Array prototypes&#8221; won&#8217;t stop until JS2<br />
I am still up for <a href="http://www.3site.eu/JSL/" rel="nofollow">JSL</a> ( JavaScript Standard Library &#8230; that I could probably update removing IE 5 and 5.5 fixes ) to normalize up to JS 1.6 or greater the Array prototype ( forEach instead of every different each, for example ) but I am sure somebody will find a perfect way to recognize an array before every library will implement standard behaviours ( or, even better, why don&#8217;t we agree about a single un-official method to retreive an array, like a toArray prototype that will return this if it is an array, slice.call(this, 0) in every other case )</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: kangax</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270361</link>
		<dc:creator>kangax</dc:creator>
		<pubDate>Mon, 12 Jan 2009 13:08:20 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270361</guid>
		<description>@BenGerrissen

Just because `[[Class]]` of certain host objects is represented as &quot;HTMLDivElement&quot; in a browser doesn&#039;t really mean that that browser supports, say, `Element.prototype` inheritance, and/or have `.constructor` referencing globally declared `HTMLDivElement` constructor, etc. : )

Specification happens to be silent in this regard.</description>
		<content:encoded><![CDATA[<p>@BenGerrissen</p>
<p>Just because `[[Class]]` of certain host objects is represented as &#8220;HTMLDivElement&#8221; in a browser doesn&#8217;t really mean that that browser supports, say, `Element.prototype` inheritance, and/or have `.constructor` referencing globally declared `HTMLDivElement` constructor, etc. : )</p>
<p>Specification happens to be silent in this regard.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: kangax</title>
		<link>http://ajaxian.com/archives/isarray-why-is-it-so-bloody-hard-to-get-right/comment-page-1#comment-270360</link>
		<dc:creator>kangax</dc:creator>
		<pubDate>Mon, 12 Jan 2009 13:01:54 +0000</pubDate>
		<guid isPermaLink="false">http://ajaxian.com/?p=5625#comment-270360</guid>
		<description>@WebReflection

I assume that&#039;s because &quot;Stack&quot; is indeed an Object object. I&#039;m not sure what kind of implementation you&#039;re talking about, but [[Class]] value is not inherited via [[Prototype]], afaik.</description>
		<content:encoded><![CDATA[<p>@WebReflection</p>
<p>I assume that&#8217;s because &#8220;Stack&#8221; is indeed an Object object. I&#8217;m not sure what kind of implementation you&#8217;re talking about, but [[Class]] value is not inherited via [[Prototype]], afaik.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

