开发者

Javascript simultaneous object and array creation

开发者 https://www.devze.com 2023-03-12 19:29 出处:网络
Why does javascript allow me to do the following. a = {two : \'World\'}; a[1] = \'Hello\'; console.log(a[1]);

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.


Because the [key] notation to access the properties of an object will accept anything as a key, including a numeric. Other things you can use include: var a={}, b={}; a{b}=1; // object a's property is the object 'b'. Rather than bad programming practice, it provides a truly unified model for objects.


See comments.

0

精彩评论

暂无评论...
验证码 换一张
取 消