Silly Javascript
blog.learnr.org
blog.learnr.org
To answer the question fully: JavaScript arrays are really just plain objects. All objects in JavaScript are simply associative arrays, and all associative arrays are string indexed. So, subscripting always causes a string conversion. The Array class provides some convenience methods with .push() .pop() to gloss over this fact, but arrays are really no different than other objects.
https://developer.mozilla.org/en/A_re-introduction_to_JavaSc...
"Javascript: The definitive guide" by O'Reily is the best.
This is not a quirk, Arrays are just objects with a special property 'length' which is set to the highest key that can be converted to an integer, plus one, and the array functions. All keys are however, strings, as with all objects.
For example,
var arr = [];
arr.foo = "hello";
arr["hello"] = function() {};
arr[40] = 56;
// arr.length = 41
It's much easier when you understand that arrays in javascript don't exist as a separate data type. They are, as I say, just objects with a couple of convenience methods+length property.I suppose it's silly at first, but hopefully at some point, you grow used to it. Crockford's book JavaScript: The Good Parts is a good book that explains many of the oddities in JS.
I actually think that it's one of JavaScript's better ideas, it's just a shame that the JavaScript doesn't have very strong getter/setter/subscripting functionality so you could implement data structures like JavaScript arrays completely in native JavaScript.
Perl has implicit type conversions similar to those of JavaScript, but the syntax of the dereference operation makes it clear what's going on:
$array[$number] $array[0] $array['0']
$hash{$key} $hash{'42'} $hash{42}
Even without the obvious variable names, you can tell from the syntax what is going to be converted to a number and what is going to be converted to a string; [] means number and {} means string.Javascript is stuck with the same syntax for both:
array[number] array[42] array["42"]
hash[key] hash[42] hash["42"]
which is apparently somewhat confusing. I know what is going to happen, but the language doesn't help me; it's easy to write code that's misleading.An array in js is just an object/dictionary, with a special 'length' property, and a few convenience methods.
Further, the 'length' property can also be confusing to newcomers, since it doesn't relate to the number of elements in the array, rather the maximum key that can be converted to an integer +1.
For example,
var arr = []; arr.foo = "hello"; arr[4] = 56;
// arr.length = 5
It's much easier when you understand that arrays in javascript don't really exist as a separate data type. They are, as I say, just objects with a couple of convenience methods+length property.
Sure, x.a should stringize 'a' to make property access work cleanly, but why when using the indexing syntax?
For example:
sgraham@gerard:~$ lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> a = {}
> a[0] = "wee"
> a[1] = "waa"
> a["1"] = "str"
> print(a[0])
wee
> print(a[1])
waa
> print(a["1"])
str
>
> a["x"] = "wee"
> a.x = "waa"
> print(a["x"])
waa
> print(a.x)
waa
>
which seems wholly more reasonable.[] syntax is for objects and arrays. As I've said, an array is just an object... Same data type.
If you didn't have a [] syntax, you wouldn't be able to use a variable to reference properties on an object.
var baz = "foo";
foo.bar == foo["bar"] == foo[baz]It makes it clear for trivial operations. Once you enter the realm of nested hashes (preferably with some arrays mixed in) the syntax turns into a royal pain in the ass.
However, for an Object (if they used {} instead of []), the property gets converted using String() before being assigned, so you cannot have duplicate values with the same String value. This actually makes sense when you consider that JavaScript isn't a hard typed language and you often don't need to type cast (which comes in handy more often than it fails a programmer).
My opinion: this guy is complaining just to complain, he could throw a _ before that 1 String and it solves his type problem completely.
[] and {} seem to be identical, except that [] one auto-increments a key-as-string in its initialization syntax.
Yes, an _ before the string would fix that particular interactive session, but it's not going to work in general.
In general, most don't use the same String value for a key/index to store different values. Just my opinion on that one, though.
Oh, and: you can use Firebug to effectively see the difference between the two.
>>> x = ["1"];
["1"]
>>> x = {"1": "1"};
Object 1=1Sorry, didn't mean to be a dick. :) This particular wart apparently got my nerd rage going.
> In general, most don't use the same String value for a key/index to store different values
Agreed, it'd generally be pretty sketchy. My current puttering around project is a "Python-in-JS" in the vein of http://objective-j.org/ which is where the desire for a "map" rather than an "object" comes from.
False. You can have anything you want in an Array, since it's just an object.
var arr = [];
arr["hello"] = 57;
arr.world = function() {};
arr[999.99] = "flibble!";
arr[54] = 9;
// arr.length now equals 55
May or may not be a good coding style, but that's a separate matter.See http://news.ycombinator.com/item?id=602004
Actually there may be a way to avoid it: redefine the toString() method of the String prototype or something like that (just an idea in the wild, haven't tried it)...
However, the same behavior is true of plain Objects.
What you're complaining about is similar to complaining that
"hello " + 3 + " world" == "hello " + "3" + " world"
var x = [];
x['3'] = 3;
x['"3"'] = "three";
alert(x);