2009-05-17 3 views
87

Следующие две различные фрагменты кода, кажется, что эквивалентно мне:В чем разница между массивом и объектом?

var myArray = Array(); 
myArray['A'] = "Athens"; 
myArray['B'] = "Berlin"; 

и

var myObject = {'A': 'Athens', 'B':'Berlin'}; 

, потому что они оба ведут себя так же, а также typeof(myArray) == typeof(myObjects) (как выход «объект»).

Есть ли разница между этими вариантами?

ответ

107

Практически все в JavaScript является объектом, так что вы можете «злоупотребление» Array объект, установив произвольные свойства на нем. Это should be considered harmful. Массивы предназначены для числовых индексов - для нечисловых ключей используйте объект.

Вот более конкретный пример, почему ключи нецифровых не «вписываются» массив:

var myArray = Array(); 
myArray['A'] = "Athens"; 
myArray['B'] = "Berlin"; 

alert(myArray.length); 

Это не будет отображаться «2», но «0» - эффективно, ни один из элементов не было добавлен в массив, только некоторые новые свойства добавлены в объект массива.

+2

myArray.length возвращает числовой индекс/ключ последнего элемента в массиве, но не действительное количество элементов. Являются ли свойства объекта Array не такими же, как значения массива? –

+1

Я просто пытался проиллюстрировать предполагаемую семантику объекта Array, если вы просто рассматриваете его как обычный объект. Связанная статья делает лучшую работу, хотя :) –

+5

В следующий раз, когда кто-то скажет, что JavaScript - хороший язык для разработки, я покажу ему этот пример. Спасибо. –

-1

{} -notation просто синтаксический сахар, чтобы сделать код лучше ;-)

JavaScript имеет много подобных конструкций, таких как строительство функций, где функция() является просто синонимом

var Func = new Function("<params>", "<code>"); 
+3

Функция конструктор ** НЕ ** синоним функции буквальной. Литерал лексически ограничен, а конструктор глобальный. '{}' - это буквальное обозначение объекта, '[]' - литеральный массив, я не уверен, в чем смысл вашего ответа. –

+0

Кроме того, объявленные функции доступны до выполнения любого кода, назначения с использованием конструктора Function недоступны до тех пор, пока не будет выполнен код, который их создает. – RobG

13

В массивах JS есть объекты, слегка модифицированные (с несколькими функциями).

функции, как:

concat 
every 
filer 
forEach 
join 
indexOf 
lastIndexOf 
map 
pop 
push 
reverse 
shift 
slice 
some 
sort 
splice 
toSource 
toString 
unshift 
valueOf 
+0

Хотя я не думаю, что все перечисленные функции встроены в каждую реализацию JS, у вас есть смысл. Другим отличием будет другой прототип (что подразумевается этими дополнительными функциями). – Rashack

5

Все в JavaScript является объектом, кроме примитивных типов.

Код

var myArray = Array(); 

создает экземпляр объекта Array, в то время как

var myObject = {'A': 'Athens', 'B':'Berlin'}; 

создает экземпляр объекта Object.

Попробуйте следующий код

alert(myArray.constructor) 
alert(myObject.constructor) 

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

Экземпляр объекта Array будет содержать все свойства и методы прототипа Array.

4

Я думаю, что я слишком метафоричен и загадочен с предыдущим ответом. Далее следует разъяснение.

Экземпляр Array, Boolean, Date, Function, Number, RegExp, String является объектом, но расширен с методами и свойствами, специфичными для каждого типа. Например, массив имеет предопределенное свойство length, а общие объекты - нет.

javascript:alert([].length+'\n'+{}.length) 

дисплеи

 
0 
undefined 

искробезопасности, интерпретатор FF Геккон также различает Массивы и общие объекты с отчетливой разницей, оценивающих языковые конструкции.

javascript: 
    ra=[ "one", "two", "three"]; ra.a=4; 
    ob={0:"one", 1:"two", 2:"three"}; ob.a=4; 
    alert(
    ra   +"\n\n"+ 
    ob   +"\n\n"+ 
    ra.toSource() +"\n\n"+ 
    ra.a   +"\t .toSource() forgot me! \n\n"+ 
    ra.length  +"\t and my length! \n\n"+ 
    ob.toSource()); 
    ps=""; for(i in ra)ps+=i+" "; alert(ps); /* NB .length is missing! */ 
    ps=""; for(i in ob)ps+=i+" "; alert(ps); 

отображения

 
one,two,three 

[object Object] 

["one", "two", "three"] 

4 .toSource() forgot me! 

3 and my length! 

({0:"one", 1:"two", 2:"three", a:4}) 

и 0 1 2 a и 0 1 2 a.

Что касается утверждения, что все объекты являются функциями:

Это не является ни синтаксически, ни семантически правильно использовать экземпляр произвольного объекта в виде функции как 123() или "abc"() или []() или {}() или obj() где obj любого типа, кроме Function, поэтому произвольный объект INSTANCE не является Function. Однако, с учетом объекта obj и его типа Array, Boolean, Date, ..., как obj стали Array, Boolean, Date, ...? Что такое Array, Boolean, Date, ...?

javascript: 
    alert([Array, Boolean, Date, Function, 
       Number, Object, RegExp, String] . join('\n\n')); 

отображает

function Array() { 
    [native code] 
} 

function Boolean() { 
    [native code] 
} 

function Date() { 
    [native code] 
} 

function Function() { 
    [native code] 
} 

function Number() { 
    [native code] 
} 

function Object() { 
    [native code] 
} 

function RegExp() { 
    [native code] 
} 

function String() { 
    [native code] 
} 

В любом случае, без экивоков, тип объекта проявляется как function определения, следовательно, о том, что все объекты являются функциями! (Язык в щеке заключается в том, что я намеренно скрыл и размыл различие экземпляра объекта с его типом! Тем не менее, это показывает, что «вы не можете иметь один без другого», объект и функция! Капитализация подчеркивает тип как противоположность примеру.)

и функциональный и объект парадигма, как представляется, фундаментальное значение для программирования и реализации встроенных примитивов JS переводчика низкого уровня, такие как Math и JSON и true.

javascript:alert([Math, JSON, true.toSource()].join("\n\n")); 

отображает

[object Math] 

[object JSON] 

(new Boolean(true)) 

Во время разработки JavaScript, объектно-ориентированный стиль программирования (ООП по - объектно-ориентированный стиль Программирование - «'s» моя собственная игра слов !) был в моде, и интерпретатор был так же окрещен Java, чтобы придать ему большую достоверность. Методы функционального программирования были отнесены к более абстрактным и эзотерическим экзаменам, изучающим теории автоматов, рекурсивных функций, формальных языков и т. Д. И, как таковые, не приемлемые. Однако сильные стороны этих формальных соображений явно проявляются в Javascript, особенно в исполнении FF в Gecko engine (то есть .toSource()).


Определение объекта для функции особенно удовлетворительно, поскольку оно определяется как отношение повторения! определяемый с помощью собственного определения!

function Function() { [native code] }
и поскольку функция является объектом то же самое справедливо и для настроения
function Object() { [native code] }.

Большинство других определений задают статическое значение терминала. Однако eval() является особенно мощным примитивом, поэтому String также может вставлять произвольные функции.

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

1

Одно практическое различие заключается при использовании JSON.stringify на array все нечисловую индексов игнорируются:

var arr = []; 
var obj = {}; 

arr['name'] = 'John'; 
obj['name'] = 'John'; 

console.log(arr); // will output [name: "John"] 
console.log(obj); // will output {name: "John"} 

JSON.stringify(arr); // will return [] 
JSON.stringify(obj); // will return {"name":"John"} 
Смежные вопросы