How to check typeof arguments?

L

-Lost

I have this generic function (JavaScript newbie here, so don't think I am going to impress
you):

function blah()
{
var container = '';
for(var i = 0; i < arguments.length; i++)
{
container += arguments + '\n';
}
alert(container);
}

Now, if I call this like:

blah('Me', 'Myself', 'I');

I get:

ALERT (you know, the alert dialog)
Me
Myself
I

However, if I call it with an array:

var arr_obj = new Array('Me', 'Myself', 'I');
blah(arr_obj);

I get:

ALERT
Me,Myself,I

I tried checking the type of the arguments object but no matter what is passed, arguments
always has a type of 'object'.

Is there something I am missing as to how to check whether or not I passed it an array or
a normal comma-separated string of values?

Also, forgive me if I am missing some fundamental thing here. Thanks!

-Lost
 
V

VK

I tried checking the type of the arguments object
but no matter what is passed, arguments always has a type of 'object'.

arguments object is - but not arguments passed to function.

function f() {
alert(typeof arguments[0]);
}

f('foobar'); // alerts 'string'
Is there something I am missing

when you do
var something+= arguments[0] + '\n';
then you call toString method for arguments[0]. If you have passed an
array reference as argument, toString for array object is called. And
for arrays toString returns comma-separated string of values.
as to how to check whether or not I passed it an array or
a normal comma-separated string of values?

if (typeof arguments == 'string') {
// string argument
}
else if (arguments instanceof Array) {
// array argument
}

Please not that you cannot uniform the check by using instanceof in
both cases. Implicit and explicit string constructors in JavaScript
are two separate entities, so say
(arguments instanceof String) will be true only for explicit string
objects created over new String("something") - something you very
rarely want to do.
 
R

RobG

-Lost said:
I have this generic function (JavaScript newbie here, so don't think I am going to impress
you):
[...]

I tried checking the type of the arguments object but no matter what is passed, arguments
always has a type of 'object'.

Is there something I am missing as to how to check whether or not I passed it an array or
a normal comma-separated string of values?

How the typeof operator works is specified in section 11.4.3 of the
ECMAScript Language specification. Depending on the expression
provided, it returns one of:

Type Result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Object (native doesn’t
implement [[Call]]) "object"
Object (native and
implements [[Call]]) "function"
Object (host) Implementation-dependent


The only tricky part is that objects are split into plain objects and
function objects.

A javascript Array is an object constructed using the built-in Array
function object as a constructor, therefore typeof Array returns
'function'. A function's arguments object isn't a function, so typeof
arguments returns 'object'.

If you want to know more about an object, you can try the constructor
property but that can be inconsistent across browsers. It may be better
to use instanceOf.

var x = [];
alert(typeof x) // object
alert(x instanceof Array); // true


To determine whether arguments passed to a function are strings, numbers
or arrays, do something like:

function foo () {
var arg, args = arguments;
var len = args.length;

for (var i=0; i<len; i++){
arg = args;

if (typeof arg == 'string' || typeof arg == 'number'){
alert('arg ' + i + ' is a string or number');
} else if (arg instanceof Array){
alert('arg ' + i + ' is an Array');
} else if (arg instanceof Function){
alert('arg ' + i + ' is a Function');
}
}
}

foo( [], 6, 'blah', function(){} );
 
L

-Lost

Thanks VK, Jim Land, and RobG! Great information from all three.

Now to absorb it all...

-Lost
 
D

dd

On Jan 27, 7:33 pm, "-Lost" <[email protected]>
wrote:

Here's a version of blah that would do what you expect:

function blah() {
var ar=arguments.length==1?arguments.split(","):arguments;
var container = '';
for(var i = 0; i < ar.length; i++)
{
container += ar + '\n';
}
alert(container);
}
 
R

RobG

On Jan 27, 7:33 pm, "-Lost" <[email protected]>
wrote:

Here's a version of blah that would do what you expect:

Please don't top-post here, reply below trimmed quotes.
function blah() {
var ar=arguments.length==1?arguments.split(","):arguments;

That will fail - the arguments object is not a string, it doesn't have
a split method. In most browsers, arguments is just an object with an
array-like length property and zero-indexed numeric property names.
In some browsers it is an Array object.
 
L

-Lost

RobG said:
Please don't top-post here, reply below trimmed quotes.


That will fail - the arguments object is not a string, it doesn't have
a split method. In most browsers, arguments is just an object with an
array-like length property and zero-indexed numeric property names.
In some browsers it is an Array object.

This *would* work though:

function blah()
{
var arg_obj = String(arguments[0]);
var arg = (arguments.length == 1) ? arg_obj.split(',') : arguments;
var container = '';
for(var i = 0; i < arg.length; i++)
{
container += arg + '\n';
}
alert(container);
}

I wonder though, should I explicitly handle the scenarios? That is, when arguments[0] is
an object (possible array), should I test for it then convert it to a string? Otherwise,
leave arguments[0] alone?

-Lost
 
R

Richard Cornford

RobG wrote:
... . In most browsers, arguments is just an object with an
array-like length property and zero-indexed numeric property
names. In some browsers it is an Array object.

The specification asserts that the - arguments - object should have the
original - Object.prototype - as its prototype, so it should not inherit
any methods or properties of arrays, and if it does that is an
implementation bug.

Richard.
 
R

RobG

The specification asserts that the - arguments - object should have the
original - Object.prototype - as its prototype, so it should not inherit
any methods or properties of arrays, and if it does that is an
implementation bug.

In Opera, the arguments object is an Array as indicated by the
following test:

function foo(){ alert(arguments instanceof Array);}
foo(); // Alerts "true" in Opera, "false" in other browsers

They probably consider it a feature rather than a bug. :) As far
as I can tell, Waldemar Horwat[1] of Netscape suggested that arguments
be an Array in JavaScript 2.0 back in 2003.


1. <URL: http://www.mozilla.org/js/language/js20/core/
functions.html#arguments-array >
 
L

-Lost

RobG said:
The specification asserts that the - arguments - object should have the
original - Object.prototype - as its prototype, so it should not inherit
any methods or properties of arrays, and if it does that is an
implementation bug.

In Opera, the arguments object is an Array as indicated by the
following test:

function foo(){ alert(arguments instanceof Array);}
foo(); // Alerts "true" in Opera, "false" in other browsers

They probably consider it a feature rather than a bug. :) As far
as I can tell, Waldemar Horwat[1] of Netscape suggested that arguments
be an Array in JavaScript 2.0 back in 2003.


1. <URL: http://www.mozilla.org/js/language/js20/core/
functions.html#arguments-array >

Baring in mind I know very little at this point, I would also imagine that Opera considers
it a feature as opposed to a bug.

The fact that Opera supports a tremendous amount of DOM features as exhibited here:

http://www.w3.org/2003/02/06-dom-support.html

....makes me think they are keenly interested in supporting the standards, regardless. As
much as I love Opera I cannot abandon Firefox. Don't ask me why.

However, my recent musings (and the very informative responses I received) make me think
that arguments should either be a String or an Array based solely upon what was given to
said function. I realize of course that arguments is an object, as it has properties, but
still think it could be a little friendlier in its implementation.

That may just be a(n uninformed) newbie point of view. *shrugs*

-Lost
 
R

Richard Cornford

RobG said:
In Opera, the arguments object is an Array as indicated by the
following test:

function foo(){ alert(arguments instanceof Array);}
foo(); // Alerts "true" in Opera, "false" in other browsers

I know, it is a bug.
They probably consider it a feature rather than a bug. :)

They would be wrong if they did. If they claim to be implementing ECMA
262 3rd Ed. then the prototype if the - arguments - object is specified
and doing anything other is a bug. Granted it is not a particularly
important bug as with everyone expecting the - arguments - object not to
be an array they are unlikely to treat it as such.
As far as I can tell, Waldemar Horwat[1] of Netscape suggested
that arguments be an Array in JavaScript 2.0 back in 2003.

It is a pity that next generation of javascript looks like an attempt to
make it more Java-like. It would probably be a better idea to not to go
in that direction and instead fix some of the ambiguities in the existing
specification. Making the - arguments - object into an array object (or
at least an array-like, as there is a specified linkage between then
'array index' properties of the - array - object and the formal parameter
properties of the Variable object) may be considered such an improvement.

Richard.
 

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,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top