Почему я могу добавлять именованные свойства в массив, как если бы это был объект?

StackOverflow https://stackoverflow.com/questions/874205

Вопрос

Следующие два разных фрагмента кода кажутся мне эквивалентными:

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

и

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

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

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

Это было полезно?

Решение

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

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

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

alert(myArray.length);

При этом будет отображаться не «2», а «0» — по сути, в массив не было добавлено никаких элементов, а к объекту массива добавлены только некоторые новые свойства.

Другие советы

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

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

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

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

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

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

дисплеи

0
undefined

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

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, особенно в том виде, как он реализован в движке Gecko компании FF (т. .toSource()).


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

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

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

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

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

Код

var myArray = Array();

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

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

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

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

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

Итак, вы увидите, что разница заключается в типе конструктора объекта.

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

Одно практическое отличие состоит в том, что при использовании 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"}

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

var arrName = [];
arrName[5] = "test";
arrName.length; // <- 6

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

А {}-нотация — это всего лишь синтаксический сахар, делающий код красивее ;-)

В JavaScript есть много подобных конструкций, например, создание функций, где function() — это просто синоним

var Func = new Function("<params>", "<code>");
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top