Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Its the isArray() function thing again

Reply
Thread Tools

Its the isArray() function thing again

 
 
Aaron Gray
Guest
Posts: n/a
 
      07-26-2008
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


 
Reply With Quote
 
 
 
 
Gregor Kofler
Guest
Posts: n/a
 
      07-26-2008
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
 
Reply With Quote
 
 
 
 
Peter Michaux
Guest
Posts: n/a
 
      07-26-2008
On Jul 26, 3:03 pm, "Aaron Gray" <(E-Mail Removed)> wrote:
> 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
 
Reply With Quote
 
Lasse Reichstein Nielsen
Guest
Posts: n/a
 
      07-26-2008
"Aaron Gray" <(E-Mail Removed)> writes:

> 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.'
 
Reply With Quote
 
Gregor Kofler
Guest
Posts: n/a
 
      07-26-2008
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
 
Reply With Quote
 
Aaron Gray
Guest
Posts: n/a
 
      07-26-2008
"Lasse Reichstein Nielsen" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> "Aaron Gray" <(E-Mail Removed)> writes:
>
>> 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

 
Reply With Quote
 
dhtml
Guest
Posts: n/a
 
      07-26-2008
On Jul 26, 3:36*pm, Lasse Reichstein Nielsen <(E-Mail Removed)> wrote:
> "Aaron Gray" <(E-Mail Removed)> writes:
> > 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

 
Reply With Quote
 
Peter Michaux
Guest
Posts: n/a
 
      07-26-2008
On Jul 26, 4:52 pm, dhtml <(E-Mail Removed)> wrote:

> > "Aaron Gray" <(E-Mail Removed)> writes:


> > > 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
 
Reply With Quote
 
RobG
Guest
Posts: n/a
 
      07-27-2008
On Jul 27, 9:52*am, dhtml <(E-Mail Removed)> wrote:
> On Jul 26, 3:36*pm, Lasse Reichstein Nielsen <(E-Mail Removed)> wrote:
>
> > "Aaron Gray" <(E-Mail Removed)> writes:
> > > 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
 
Reply With Quote
 
dhtml
Guest
Posts: n/a
 
      07-27-2008
On Jul 26, 7:10*pm, RobG <(E-Mail Removed)> wrote:
> On Jul 27, 9:52*am, dhtml <(E-Mail Removed)> wrote:
>
>
>
> > On Jul 26, 3:36*pm, Lasse Reichstein Nielsen <(E-Mail Removed)> wrote:

>
> > > "Aaron Gray" <(E-Mail Removed)> writes:
> > > > 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


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Its a bird, its a plane, its.. um, an Attribute based System? thunk Ruby 14 04-03-2010 10:08 AM
Its a bird, its a plane, its.. um, an Attribute based System? thunk Ruby 0 04-01-2010 10:25 PM
Its a bird, its a plane, no ummm, its a Ruide thunk Ruby 1 03-30-2010 11:10 AM
Call again a variadic function (... variable number of arguments)with same arguments that its variadic wrapper moreau.steve@gmail.com C Programming 3 12-31-2008 07:13 AM
one thing solved, but other terrible thing occur... Zam ASP General 1 03-14-2005 06:09 PM



Advertisments