Подтвердить что ты не робот

Являются ли Javascript массивами примитивов? Строки? Объекты?

Являются ли массивы просто скрытыми объектами? Почему, почему нет? Каким образом (они) они (такие/нет)?

Я всегда думал о массивах и объектах в JS по существу одинаково, в первую очередь потому, что их доступ идентичен.

var obj = {'I': 'me'};
var arr = new Array();
arr['you'] = 'them';

console.log(obj.I);
console.log(arr.you);
console.log(obj['I']);
console.log(arr['you']);

Я вводил в заблуждение/ошибочно/неправильно? Что мне нужно знать о литералах JS, примитивах и строках/объектах/массивах/etc...?

Являются ли массивы/объекты просто строками в маскировке? Почему, почему нет? Каким образом (они) они (такие/нет)?

4b9b3361

Ответ 1

Массивы - это объекты.

Однако, в отличие от обычных объектов, массивы имеют определенные особенности.

  • Массивы имеют дополнительный объект в цепочке прототипов, а именно Array.prototype. Этот объект содержит так называемые методы массива, которые можно вызвать в экземплярах массива. (Список методов находится здесь: http://es5.github.com/#x15.4.4)

  • Массивы имеют свойство length (которое является живым, ergo, оно автоматически обновляется) (читайте здесь: http://es5.github.com/#x15.4.5.2)

  • Массивы имеют специальный алгоритм определения новых свойств (читайте здесь: http://es5.github.com/#x15.4.5.1). Если вы установите новое свойство в массив, и это имя свойства является sting, которое может быть принудительно применено к целочисленному числу (например, '1', '2', '3' и т.д.), Тогда применяется специальный алгоритм (он определен на стр. 123 в спецификации)

Помимо этих трех вещей, массивы похожи на обычные объекты.

Читайте о массивах в спецификации: http://es5.github.com/#x15.4

Ответ 2

Объекты представляют собой неупорядоченную карту из строковых ключей в значения, массивы представляют собой упорядоченный список значений (с целыми ключами). Это главное отличие. Они оба не примитивны, поскольку они состоят из нескольких значений, что также подразумевает передачу по ссылке в JavaScript.

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

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

Ответ 3

Строки могут быть либо примитивными, либо объектами, в зависимости от того, как они были объявлены.

var str = 'yes';

Дает вам примитив, а

var str = new String('yes');

предоставит вам объект String.


Все массивы одинаковы (независимо от того, были ли они определены с помощью [] или нового массива()), относятся к типу объекта и наследуются от прототипа объекта "Массив". В Javascript нет реальных классов, все это объект, и есть системный объект, называемый Array. Он имеет свойство, называемое 'prototype' (объекта типа), и когда вы используете новое ключевое слово для объекта с свойством prototype, он создает экземпляр со ссылкой на содержимое прототипа и сохраняет его в вашей переменной. Таким образом, все массивы, которые вы когда-либо использовали в Javascript, являются объектами и экземплярами свойства прототипа Array.

В любом случае, хотя массивы действительно являются объектами, они ведут себя как массивы из-за их полезных свойств и функций (таких как длина, срез, толчок и т.д.).

Еще одно замечание, хотя я сказал, что нет классов, когда вы это делаете:

console.log(Object.prototype.toString.call(your_object));

он даст вам строку в форме [object Object]. Но полезно то, что когда вы вызываете его с помощью массива, вы получаете [object Array] то же самое с функциями, которые дают [object Function] и ряд других системных типов, которые помогают дифференцировать обычные объекты и массивы (так как typeof оператор всегда просто возвращает строку "объект" ).

Попробуйте это

var a = Array;

и зайдите в firebug и изучите содержимое a, особенно это свойство 'prototype'.

Изменить: Немного изменил формулировку, чтобы быть более правильным. Фактически, когда вы используете новое ключевое слово, он создает экземпляр, который ссылается на объект прототипа. Таким образом, любые изменения, внесенные в прототип после объявления экземпляра, будут по-прежнему влиять на экземпляр.

Изменить: В ответ на ваш последний пересмотренный вопрос (массивы/объекты фактически замаскированы строками): Нет. Это объекты, как я объяснил. Строки являются либо примитивным типом, либо типом объекта (экземпляр объекта String), который содержит примитивный эквивалент в качестве одного из его свойств.

Ответ 4

Массивы не являются примитивами в Javascript, они являются объектами. Главное различие заключается в том, что в результате, когда вы передаете массив функции, он передается по ссылке, а не по значению.

Так что да! Массивы - это объекты в javascript, с полномасштабным Array.prototype и всем (не трогайте это, хотя...)

Путаница возникает из-за того, что javascripts позволяет вам получить доступ к атрибутам объекта двумя способами:

myObj.attribute или myObj [ "атрибут" ]

Действительно, что делает массив массивом не имеет ничего общего с тем, как вы храните данные - любой объект может хранить значения с использованием синтаксиса, который вы используете для хранения массива, - что делает массив массивом фактом, что методы массива (например, shift() и sort()) определены для Array.prototype.

Ответ 5

Попытка быть кратким из того, что, по моему мнению, имеет наибольшее значение: в массивах есть несколько методов, которые нет у объектов. В том числе:

  • Длина
  • толчок
  • поп

Объект, объявленный как var x = {foo:bar}, не имеет доступа к методу .length(). Это оба объекта, но с массивом как своего рода супермножество с методами, упомянутыми выше.

Я не чувствую, что это даже близко к тому, чтобы быть стандартом Крокфорда с точки зрения объяснения, но я стараюсь быть кратким.

Если вы хотите получить некоторые быстрые результаты, откройте Firebug или вашу javascript-консоль и попробуйте Array.prototype и Object.prototype, чтобы увидеть некоторые подробности.

Обновление: В вашем примере вы объявите массив, а затем выполните:

foo['bar'] = 'unexpectedbehaviour';

приведет к неожиданным результатам и не будет доступен в простых циклах, таких как:

var foo=[0,1];
foo['bar'] = 2;

for(var i=0;i<foo.length;i++){
    console.log(foo[i]);
}

//outputs: 
//0
//1

Массив может принимать foo['bar']=x или foo.bar=y как объект, но не обязательно будет доступен, как показано выше.

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

Ответ 6

В JavaScript у вас есть несколько типов, все остальное - это объект. Типы в JavaScript: boolean, number и string. Существуют также два специальных значения: "null" и "undefined".

Итак, квест "это массив JavaScript?"? немного неоднозначна. Да, массив JavaScript - это "объект", но это не экземпляр "Объект". Массив JavaScript - это экземпляр "Массив". Хотя все объекты наследуются от Object; вы можете просмотреть цепочку наследования MDC. Кроме того, массивы имеют несколько иные свойства, чем объект. Массивы имеют свойство .length. Они также имеют методы .slice(), .join() и т.д.

Douglas Crockford предоставляет приятный survey особенности языка. В его обзоре обсуждаются различия, о которых вы спрашиваете. Кроме того, вы можете узнать больше о разнице между литералами и конструкторами в вопросе # 4559207.

Ответ 7

Массивы являются объектами, но имеют особый характер. Объекты представляют собой коллекции значений, индексированных ключами (в нотации Javascript, {'key': 'value'}), тогда как массивы - это объекты, ключи которых являются числовыми (с несколькими функциями и свойствами). Основное различие между ними очевидно, когда вы используете цикл for each - объект будет перебирать все значения в своих свойствах, тогда как Array вернет ключи вместо этого. Вот ссылка на JSFiddle, демонстрирующую разницу, - обратите внимание, что первый for each, который использует массив, возвращает индексы, а не значения; напротив, второй for each возвращает фактические значения на этих клавишах.