473,396 Members | 1,785 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Its the isArray() function thing again

I know this has probably been argued to death, but I am going to raise it
fresh again, and basically lets have an unofficial 'isArray()' contest that
we can hopefully put it to rest as best as we can.

I have found things that work perfectly well as long as you don't try them
on MSIE, ie adding Object and Array prototype isArray functions, thus :-

Object.prototype.isArray = function() { return false }
Array.prototype.isArray = function() { return true }

This falls down on builtin browser types in IE, so is no good.

The one version that I have seen is :-

function isArray( a) { return typeof a.push == "function" }

Prototype for all its "failings" extends object and provides :-

Object.extend(Object, {
isArray: function(object) {
return object != null && typeof object == "object" &&
'splice' in object && 'join' in object;
}
});

So checking of non null and splice and join maybe better than just checking
for push.

So something like :-

function isArray( o) { return o != null && typeof o == "object" &&
'push' in o }

But I am not sure when 'in' was actually introduced.

function isArray( o) { return o != null && typeof o == "object" &&
typeof o.push == "function" }

Would probably do best/better. This is what I have settled on for now.

Then there was the advice to use === rather than ==, but I dont know when
that was introduced too, or whether it is really necessary as == works just
as well AFAICS.

Any critisisms, advances, or advice ?

Aaron
Jul 26 '08 #1
18 1812
On Jul 26, 3:03 pm, "Aaron Gray" <ang.use...@gmail.comwrote:
I know this has probably been argued to death, but I am going to raise it
fresh again, and basically lets have an unofficial 'isArray()' contest that
we can hopefully put it to rest as best as we can.
In your actual application code, why are you ever having any trouble
knowing if a variable references an Array or not? If a function's API
states it should recieve an array argument, then just send it an array
argument. If it states it should receive a number, don't send it an
array. Be careful about bringing the baggage of focusing on type
checking and casting from languages like Java or C++ to your
JavaScript programming.
I have found things that work perfectly well as long as you don't try them
on MSIE, ie adding Object and Array prototype isArray functions, thus :-

Object.prototype.isArray = function() { return false }
Array.prototype.isArray = function() { return true }
Augmenting built in prototypes with generic names like "isArray" is
likely to collide in an envronment where multiple authors are writing
the JavaScript.

http://peter.michaux.ca/article/7979

This falls down on builtin browser types in IE, so is no good.

The one version that I have seen is :-

function isArray( a) { return typeof a.push == "function" }
That is a very wimpy test in general.

Prototype for all its "failings" extends object and provides :-
The quotation marks are not necessary.

Object.extend(Object, {
isArray: function(object) {
return object != null && typeof object == "object" &&
'splice' in object && 'join' in object;
}
});
Why they think writing

Object.isArray

is any different than

PrototypeJS.isArray

I will never understand.

So checking of non null and splice and join maybe better than just checking
for push.

So something like :-

function isArray( o) { return o != null && typeof o == "object" &&
'push' in o }

But I am not sure when 'in' was actually introduced.

function isArray( o) { return o != null && typeof o == "object" &&
typeof o.push == "function" }
So if I define a new object in JavaScript with a push function it will
pass your test. That is a very weak test.

Would probably do best/better. This is what I have settled on for now.

Then there was the advice to use === rather than ==, but I dont know when
that was introduced too,
http://pointedears.de/scripts/es-matrix/

or whether it is really necessary as == works just
as well AFAICS.
They are not the same. == and != do type coercion.

http://developer.mozilla.org/en/docs...ison_Operators

Any critisisms, advances, or advice ?
What's wrong with

if (obj instanceof Array) {
// do stuff
}

http://developer.mozilla.org/en/docs...nceof_Operator

Peter
Jul 26 '08 #2
"Aaron Gray" <an********@gmail.comwrites:
I know this has probably been argued to death, but I am going to raise it
fresh again, and basically lets have an unofficial 'isArray()' contest that
we can hopefully put it to rest as best as we can.
Is there a setting where

obj instanceof Array

fails to detect an Array?

....
Prototype for all its "failings" extends object
That's one failing right there :)
I thought they stopped doing that in later versions?
and provides :-

Object.extend(Object, {
isArray: function(object) {
return object != null && typeof object == "object" &&
'splice' in object && 'join' in object;
Sigh. Feature detection is good for detecting features. This is detection
by inference. This is as bad as
var isIE = document.all ? 1 : 0;
(ok, slightly better, the isIE example has more bad points than it has
keywords)
So checking of non null and splice and join maybe better than just checking
for push.
"maybe" is the operative word. I.e., it's shooting blind and hoping to
be lucky.
So something like :-

function isArray( o) { return o != null && typeof o == "object" &&
'push' in o }

But I am not sure when 'in' was actually introduced.
JScript 5.6
JavaScript 1.4

Same versions as "instanceof", btw.
function isArray( o) { return o != null && typeof o == "object" &&
typeof o.push == "function" }

Would probably do best/better. This is what I have settled on for now.
And when we implement a stack:

function Stack() {}
Stack.prototype.push = function(o) {
this.head = {elem: o, next: this.head }
};
Stack.prototype.pop = function() {
var head = this.head;
if (head) {
var elem = head.elem;
this.head = head.next;
return elem;
}
};

it suddently qualifies as an array?

An object is an Array if it inherits Array.prototype. That's the
prototype based definition of inheritance.
Then there was the advice to use === rather than ==, but I dont know when
that was introduced too, or whether it is really necessary as == works just
as well AFAICS.
It's the same when dealing with objects. The "==" operator performs
type conversion in some cases, whereas the "===" requires both
operands to have the same type. When the operands are objects, they
work exactly the same,
Any critisisms, advances, or advice ?
What problem are you trying to solve?
Why?
In any case, don't try to be clever. Either use "instanceof", or, if
it's *really* necessary to support ancient browsers, test simple
things:

function isArray(o) {
return o && o.constructor == Array;
}

It's easy to cheat, but anybody actively trying to cheat is going to
succeede anyway.

/L
--
Lasse Reichstein Nielsen
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 26 '08 #3
Aaron Gray meinte:
But I am not sure when 'in' was actually introduced.
Then there was the advice to use === rather than ==, but I dont know when
that was introduced too
Before he does it:
http://pointedears.de/scripts/es-matrix/

Gregor
--
http://photo.gregorkofler.at ::: Landschafts- und Reisefotografie
http://web.gregorkofler.com ::: meine JS-Spielwiese
http://www.image2d.com ::: Bildagentur für den alpinen Raum
Jul 26 '08 #4
Aaron Gray meinte:
I know this has probably been argued to death, but I am going to raise it
fresh again, and basically lets have an unofficial 'isArray()' contest that
we can hopefully put it to rest as best as we can.
Crockford suggests

var is_array = function(v) {
return v && typeof v === "object" && v.constructor === Array;
}

(wont work on arrays in other windows/frames)

or

var is_array = function(v) {
return v && typeof v === "object" && typeof v.length === "number" &&
typeof v.splice === "function" && !(v.propertyIsEnumerable("length"));
}

(I suppose he took splice() because it's a relatively "rare" method)

Gregor
--
http://photo.gregorkofler.at ::: Landschafts- und Reisefotografie
http://web.gregorkofler.com ::: meine JS-Spielwiese
http://www.image2d.com ::: Bildagentur für den alpinen Raum
Jul 26 '08 #5
"Lasse Reichstein Nielsen" <lr*@hotpop.comwrote in message
news:4p**********@hotpop.com...
"Aaron Gray" <an********@gmail.comwrites:
>I know this has probably been argued to death, but I am going to raise it
fresh again, and basically lets have an unofficial 'isArray()' contest
that
we can hopefully put it to rest as best as we can.

Is there a setting where

obj instanceof Array

fails to detect an Array?
Don't know. But I had forgotten about 'instanceof Array' and thats exactly
what I need for this specific problem.

I think people use the other 'weaker' methods to allow inclusion of array
like objects as well as Arrays.
In any case, don't try to be clever. Either use "instanceof", or, if
it's *really* necessary to support ancient browsers, test simple
things:

function isArray(o) {
return o && o.constructor == Array;
}
Thomas is right, I really should read ECMA-262 properly.

Many thanks,

Aaron

Jul 26 '08 #6
On Jul 26, 3:36*pm, Lasse Reichstein Nielsen <l...@hotpop.comwrote:
"Aaron Gray" <ang.use...@gmail.comwrites:
I know this has probably been argued to death, but I am going to raise it
fresh again, and basically lets have an unofficial 'isArray()' contest that
we can hopefully put it to rest as best as we can.

Is there a setting where

* obj instanceof Array

fails to detect an Array?
There is: When obj is an Array in a different frame than the Array
constructor, it would be constructed via a different Array
constructor, and so obj instanceof Array would have to be false.
otherFrame.obj instanceof otherFrame.Array would be true, though.

Prototype for all its "failings" extends object
That was quite a long time ago.
That's one failing right there :)
I thought they stopped doing that in later versions?
Yes, they did.

Garrett

/L
Jul 26 '08 #7
On Jul 26, 4:52 pm, dhtml <dhtmlkitc...@gmail.comwrote:
"Aaron Gray" <ang.use...@gmail.comwrites:
Prototype for all its "failings" extends object

That was quite a long time ago.
They are still extending "Object" unnecessarily with function-valued
properties that could be added to any object. Adding them to "Object"
is just confusing, in my opinion. They also choose very generic names
in shared namespaces which is another problem of theirs.

http://www.prototypejs.org/api/object

Peter
Jul 27 '08 #8
On Jul 27, 9:52*am, dhtml <dhtmlkitc...@gmail.comwrote:
On Jul 26, 3:36*pm, Lasse Reichstein Nielsen <l...@hotpop.comwrote:
"Aaron Gray" <ang.use...@gmail.comwrites:
I know this has probably been argued to death, but I am going to raise it
fresh again, and basically lets have an unofficial 'isArray()' contest that
we can hopefully put it to rest as best as we can.
Is there a setting where
* obj instanceof Array
fails to detect an Array?

There is: When obj is an Array in a different frame than the Array
constructor, it would be constructed via a different Array
constructor, and so obj instanceof Array would have to be false.
otherFrame.obj instanceof otherFrame.Array would be true, though.
Prototype for all its "failings" extends object

That was quite a long time ago.
That's one failing right there :)
I thought they stopped doing that in later versions?

Yes, they did.
They stopped extending Object.prototype.

--
Rob
Jul 27 '08 #9
On Jul 26, 7:10*pm, RobG <rg...@iinet.net.auwrote:
On Jul 27, 9:52*am, dhtml <dhtmlkitc...@gmail.comwrote:
On Jul 26, 3:36*pm, Lasse Reichstein Nielsen <l...@hotpop.comwrote:
"Aaron Gray" <ang.use...@gmail.comwrites:
I know this has probably been argued to death, but I am going to raise it
fresh again, and basically lets have an unofficial 'isArray()' contest that
we can hopefully put it to rest as best as we can.
Is there a setting where
* obj instanceof Array
fails to detect an Array?
There is: When obj is an Array in a different frame than the Array
constructor, it would be constructed via a different Array
constructor, and so obj instanceof Array would have to be false.
otherFrame.obj instanceof otherFrame.Array would be true, though.
Prototype for all its "failings" extends object
That was quite a long time ago.
That's one failing right there :)
I thought they stopped doing that in later versions?
Yes, they did.

They stopped extending Object.prototype.
Ah, right that's what I was thinking about. Modifying
Object.prototype. That was very bad.

They still extend Object, which is not as bad. They add a clone()
method to Object, and clone is an ES3.1 Proposal. I asked Allen about
that

Object.clone is proposed for ES 3.1. I did mention it on the list, but
Allen was replying to a lot of responders, so he probably missed what
I wrote:

| It seems like Object.clone might create compatibility with existing
| code. There is already a widespread use of an Object.clone on the
web.
Garrett
--
Rob
Jul 27 '08 #10
"dhtml" wrote:

[snip]
"Aaron Gray" wrote:
[snip]
Prototype for all its "failings" extends object
[snip]
They still extend Object, which is not as bad. They add a clone()
method to Object, and clone is an ES3.1 Proposal. I asked Allen about
that

Object.clone is proposed for ES 3.1. I did mention it on the list, but
Allen was replying to a lot of responders, so he probably missed what
Who is "Allen"?
I wrote:

| It seems like Object.clone might create compatibility with existing
| code. There is already a widespread use of an Object.clone on the
web.
"compatibility" or "incompatibility" with Prototype.js' Object.clone?
It looks to me like there will be incompatibility as Prototype.js'
Object.clone is a shallow copy and the ES3.1 Object.clone is a much
deeper clone of an Object. This is why adding generically named
properties in shared namespaces is a problem. The Prototype.js
developers have been burned by this at least a few times in the past
two years. That may imply they have influence over the evolution of
JavaScript and the DOM. Unfortunately it also means they are causing
unnecessary maintenance headaches for Prototype.js users.

Peter
Jul 27 '08 #11
On Jul 27, 5:55*pm, Peter Michaux <petermich...@gmail.comwrote:
>
Object.clone is proposed for ES 3.1. I did mention it on the list, but
Allen was replying to a lot of responders, so he probably missed what
I wrote.

Who is "Allen"?
Allen Wirfs-Brock, http://preview.tinyurl.com/5hf4na

--Jorge.
Jul 27 '08 #12
On Jul 27, 7:02*pm, Jorge <jo...@jorgechamorro.comwrote:
On Jul 27, 5:55*pm, Peter Michaux <petermich...@gmail.comwrote:
Object.clone is proposed for ES 3.1. I did mention it on the list, but
Allen was replying to a lot of responders, so he probably missed what
I wrote.
Who is "Allen"?

Allen Wirfs-Brock,http://preview.tinyurl.com/5hf4na
https://mail.mozilla.org/pipermail/e...hread.html#324
https://mail.mozilla.org/pipermail/e...read.html#3227

--Jorge.
Jul 27 '08 #13
Jorge wrote:
On Jul 27, 5:55 pm, Peter Michaux wrote:
>
Object.clone is proposed for ES 3.1. I did mention it on the list,
but
Allen was replying to a lot of responders, so he probably missed
what
I wrote.

Who is "Allen"?
Allen Wirfs-Brock, http://preview.tinyurl.com/5hf4na

There is little point in posting tinyurl URLs as nobody in their right
mind would follow one, just as nobody in their right mind would follow a
URL found in a spam post.

Richard.

Jul 27 '08 #14
On Jul 27, 11:53*pm, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:
>
Allen Wirfs-Brock,http://preview.tinyurl.com/5hf4na

There is little point in posting tinyurl URLs as nobody in their right
mind would follow one, just as nobody in their right mind would follow a
URL found in a spam post.
Not even if it points to a preview, like that one ?
We Mac users aren't so frightened of urls.

--Jorge.
Jul 27 '08 #15
dhtml wrote:
<snip>
Object.clone is proposed for ES 3.1. I did mention it on the
list, but Allen was replying to a lot of responders, so he
probably missed what I wrote:

| It seems like Object.clone might create compatibility with
| existing code. There is already a widespread use of an
| Object.clone on the web.
Assuming you mean "incompatibility" where you wrote "compatibility",
then ES 3.1 defining an - Object.clone - method is not an issue unless
it is defined as a read-only (or ES 3.1's equivalent of read-only). If a
script loads in into (and is executed in) an ES 3.1 environment and that
script assignees its own method to - Obejct.clone - then so long as that
assignment succeeds code in the same context that uses - Object.clone -
will be using the version it is expecting to use.

Richard.

Jul 27 '08 #16
Jorge wrote:
On Jul 27, 11:53 pm, Richard Cornford wrote:
>>Allen Wirfs-Brock,http://preview.tinyurl.com/5hf4na

There is little point in posting tinyurl URLs as nobody
in their right mind would follow one, just as nobody in
their right mind would follow a URL found in a spam post.

Not even if it points to a preview, like that one ?
How would it be possible to determine what it points to without
following it?
We Mac users aren't so frightened of urls.
It is probably best if I don't comment on that.

Richard.

Jul 27 '08 #17
On Jul 28, 12:26*am, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:
>
It is probably best if I don't comment on that.
Thanks. I also know about *that* contest.

--Jorge.
Jul 27 '08 #18
On Jul 27, 3:22*pm, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:
dhtml wrote:
>
| *It seems like Object.clone might create compatibility with
| *existing code. There is already a widespread use of an
| *Object.clone on the web.

Assuming you mean "incompatibility" where you wrote "compatibility",
I remember thinking "compatibility issue" when I was typing.
then ES 3.1 defining an - Object.clone - method is not an issue unless
it is defined as a read-only (or ES 3.1's equivalent of read-only). If a
script loads in into (and is executed in) an ES 3.1 environment and that
script assignees its own method to - Obejct.clone - then so long as that
assignment succeeds code in the same context that uses - Object.clone -
will be using the version it is expecting to use.
Where "it" is the PrototypeJS library itself.

A user of PrototypeJS would have to contend with things like:

<script>
Object.clone( o };
</script>

<script src="prototype-1.7.js"></script>

<script>
Object.clone( o };
</script>

PrototypeJS.cloneObject would be safer.

Garrett
Richard.
Jul 28 '08 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: Laphan | last post by:
Hi All I'm using .getRows() with a local var array instead of doing a recursive loop so that I'm being a good ASP newvbie and closing my object i/o's (the recordset in this case) as quick as...
33
by: Matt Kruse | last post by:
I'm seeking the most robust and backwards-compatible (ie, no instanceof) isArray function. Here's what I have: function defined(o) { return typeof(o)!="undefined"; } function isArray(o) {...
8
by: =?ISO-8859-1?Q?Norbert_P=FCrringer?= | last post by:
Hello again, I've got a type variable, e.g. Type type; Now I want to know whether the type represents an Array type (System.Array). type.IsArray results false because System.Array is an...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.