Javascript одновременное создание объектов и массивов - PullRequest
4 голосов
/ 15 июня 2011

Почему javascript позволяет мне делать следующее.

a = {two : 'World'};
a[1] = 'Hello';
console.log(a[1]);
console.log(a.two);

вывод

Hello
World

Разве это не должно жаловаться, что я пытаюсь использовать объект в качестве массива? Кстати, это работает с чем угодно, например

b = new Date();
b[1] = 'Wow';
console.log(b[1]);

вывод

wow

Есть ли для этого смысл? Мне кажется, это плохая практика программирования.

Ответы [ 5 ]

4 голосов
/ 15 июня 2011

В Javascript все массивы являются объектами.Нет жесткой разделительной линии между ними.Массивы имеют определенные свойства и методы, но реализуются как объекты.

Синтаксис [1] является одним из двух эквивалентных операторов-членов Javascript .Эти два значения эквивалентны:

var foo = {};
foo.bar = 'foobar';
foo['bar'] = 'foobar';

Однако с помощью точечной нотации (foo.bar) вы можете получить доступ только к свойствам, которые являются действительными идентификаторами Javascript.Это означает:

последовательность буквенно-цифровых символов, включая знак подчеркивания ("_") и знак доллара ("$"), которые не могут начинаться с цифры ( source )

Вы можете установить свойства любого объекта Javascript - массива, объекта, объекта Date, строки, числа - таким образом, поскольку все они происходят от одного и того же типа объекта.

3 голосов
/ 15 июня 2011

Вы не рассматриваете объект как массив - вы используете числовые ключи в объекте.Так же, как они оба действительны:

var o = { "test":1 };
o["test2"] = 2;

, таковы и они:

var o = { 1: "test" };
o[2] = "test2";

Редактировать : Как указано в комментарии ниже, приведенный выше синтаксис фактически вводит в заблуждение, поскольку 1 преобразуется в строку в обоих случаях - технически это точно так же, как

var o = { "1": "test" };

, как вы можете видеть здесь:

var o = {1:"test"};
for (i in o) console.log(i, i===1, i==="1"); // 1 false true
3 голосов
/ 15 июня 2011

Разве это не должно жаловаться, что я пытаюсь использовать объект в качестве массива?

Нет.Числовые свойства разрешены.Обозначение в квадратных скобках [] используется на объектах для ключей, которые не являются допустимыми идентификаторами JavaScript.Не только в массивах.

a[ "some-invalid***identifier" ] = 'some value';

Кстати, это работает с чем угодно, например

Да, по той же причине.new Date() возвращает объект, свойства которого могут быть назначены с помощью точечных или квадратных скобок.

0 голосов
/ 15 июня 2011

Честно говоря, я думаю, что вывод консоли может быть довольно поучительным:

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: ...

Как видите, это оба просто объекты, один наследует от общего объекта, а другой от даты. Как и любому другому объекту, им может быть назначена пара ключ / значение, где ваша цифра 1 просто преобразуется в строку.

Это определенно грязное кодирование, если вы используете таким образом, но это довольно важная иллюстрация принципов JavaScript. Существует множество полезных способов расширения объектов, которые синтаксически похожи на то, что вы делаете.

0 голосов
/ 15 июня 2011
Потому что нотация [ключ] для доступа к свойствам объекта будет принимать все в качестве ключа, в том числе числовой. Другие вещи, которые вы можете использовать, включают в себя: var a = {}, b = {}; а {Ь} = 1; // Свойство объекта a является объектом 'b'. Вместо плохой практики программирования, он обеспечивает действительно унифицированную модель для объектов.


Смотрите комментарии.

...