Why does javascript allow me to do the following.
a = {two : 'World'};
a[1] = 'Hello';
console.log(a[1]);
console.log(a.two);
the output is
Hello
World
Shouldn't it complain that I am trying to use an object as an Array? This works with anything by the way, like so
b = new Date();
b[1] =开发者_如何学Go 'Wow';
console.log(b[1]);
the output is
wow
Is there a use for this? It seems to me like a bad programing practice.
In Javascript, all arrays are objects. There is no hard-and-fast dividing line between the two. Arrays have certain properties and methods, but are implemented as objects.
The syntax [1]
is one of the two equivalent Javascript member operators. These two are equivalent:
var foo = {};
foo.bar = 'foobar';
foo['bar'] = 'foobar';
However, with the dot notation (foo.bar
), you can only access properties that are valid Javascript identifiers. This means:
a sequence of alphanumerical characters, also including the underscore ("_") and dollar sign ("$"), that cannot start with a number (source)
You can set the properties of any Javascript object -- array, object, Date object, string, number -- in this fashion, since they all derive from the same Object type.
Shouldn't it complain that I am trying to use an object as an Array?
No. Numeric properties are allowed. The square bracket notation []
is used on Objects for keys that are not valid javascript identifiers. Not just on Arrays.
a[ "some-invalid***identifier" ] = 'some value';
This works with anything by the way, like so
Yes, same reason. new Date()
returns an object to which properties can be assigned either via dot or square bracket notation.
You're not treating an object like an array - you're using numeric keys in an object. Just as these are both valid:
var o = { "test":1 };
o["test2"] = 2;
so are these:
var o = { 1: "test" };
o[2] = "test2";
Edit: As the comment below points out, the above syntax is actually misleading, as 1
gets converted to a string in both cases - so technically, this is exactly the same as
var o = { "1": "test" };
as you can see here:
var o = {1:"test"};
for (i in o) console.log(i, i===1, i==="1"); // 1 false true
Honestly, I think the console output of this can be pretty enlightening:
var a = {two: "World"};
a[1] = "Hello";
console.log(a);
// 1: "Hello"
// two: "World"
// > __proto__: Object
var b = new Date();
b[1] = 'Wow';
console.dir(b[1]); // console.log just returns the timestamp
// 1: "Wow"
// v __proto__: Date
// > constructor: function Date() { [native code] }
// > getDate: ...
As you can see, these are both just objects, one inheriting from the generic Object and the other from Date. Just like any other object, they can be assigned a key/value pair, where your 1 is just being converted into a string.
It's definitely messy coding if you use it that way, but it's a pretty important illustration of JavaScript principles. There are plenty of useful ways to extend objects that are syntactically similar to what you're doing.
See comments.
精彩评论