Вопрос

А именно, как работает следующий код:

var sup = new Array(5);
sup[0] = 'z3ero';
sup[1] = 'o3ne';
sup[4] = 'f3our';
document.write(sup.length + "<br />");

выведите '5' для длины, когда все, что вы сделали, это установили различные элементы?

Моя "проблема" с этим кодом заключается в том, что я не понимаю, как length изменяется без вызова getLength() или setLength() способ.Когда я делаю что-либо из следующего:

a.length
a['length']
a.length = 4
a['length'] = 5

для объекта, не являющегося массивом, он ведет себя как dict / ассоциативный массив.Когда я делаю это с объектом array, это имеет особое значение.Какой механизм в JavaScript позволяет этому произойти?Есть ли в javascript какой-то тип системы свойств, который переводит

a.length
a['length']

в методы "get" и

a.length = 4
a['length'] = 5

в методы "набора"?

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

Решение

Все в JavaScript является объектом.В случае возникновения Array, тот самый length свойство возвращает размер внутренней области хранения для индексированных элементов массива.Некоторая путаница может возникнуть из-за того, что [] оператор работает как с числовыми, так и со строковыми аргументами.Для массива, если вы используете его с числовым индексом, он возвращает / задает ожидаемый индексированный элемент.Если вы используете его со строкой, он возвращает / устанавливает именованное свойство для объекта array - если строка не соответствует числовому значению, тогда он возвращает индексированный элемент.Это происходит потому, что в JavaScript индексы массива принудительно преобразуются в строки с помощью неявного toString() позвони.Честно говоря, это просто еще одна из тех вещей, которые заставляют вас почесать в затылке и сказать: "JavaScript, вот, вот почему они смеются над тобой".

Фактическое базовое представление может отличаться в разных браузерах (а может и нет).Я бы не стал полагаться ни на что, кроме интерфейса, который предоставляется при работе с ним.

Вы можете узнать больше о массивах Javascript по адресу MDN.

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

Чтобы добавить к ответу тванфоссона'а:В ECMA-262 (я полагаю, спецификация 3.0) массивы просто определяются как имеющие такое поведение для настройки свойств (см. 15.4.5.1).Нет никакого общего механизма, лежащего в его основе (по крайней мере, на данный момент) - это просто то, как он определен, и как должны вести себя интерпретаторы javascript.

Это действительно зависит от того, что вы собираетесь с этим делать.

[].length является "волшебным".
На самом деле он не возвращает количество элементов в массиве.Он возвращает самый большой установленный индекс в массиве.

var testArr = [];  testArr[5000] = "something";  testArr.length; // 5000

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

Так что не полагайтесь на методы defineGetter и defineSetter или даже, на самом деле, __proto__ методы, если только вы не знаете, на какие браузеры вы ориентируетесь, а на какие нет.

Это изменится в будущем, когда зарегистрированные приложения, написанные на ECMAScript Next / 6, будут иметь доступ к большему количеству.

Браузеры, совместимые с ECMAScript 5, уже начинают предлагать get и set магические методы в объектах - и это еще не все...... но, вероятно, пройдет некоторое время, прежде чем вы сможете отказаться от поддержки oldIE и тонны смартфонов и так далее...

Важно знать, что когда вы делаете sup['look'] = 4; вы не используете ассоциативный массив, а скорее изменяете свойства объекта sup.Это эквивалентно sup.look = 4; поскольку вы можете динамически добавлять свойства к объектам javascript в любое время. sup['length'] было бы для экземпляра вывести 5 в вашем первом примере.

Если вы намереваетесь реализовать объекты с доступом, подобным массиву, то Статья Array Mozilla dev center это отличный ресурс.К сожалению, я не знаю подробностей реализации массива, но в этой статье есть много подробностей.

Array объект наследует caller, constructor, length, и name свойства из Function.prototype.

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

arr[5] = "yo"

Вышесказанное является синтаксический сахар для

arr.insert(5,"yo")

именно так вы бы добавляли материал к обычному объекту.Это то, что находится внутри вставить метод, который изменяет значение arr.length

Смотрите мою реализацию типа CustomArray здесь: http://jsfiddle.net/vfm3vkxy/4/

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

На самом деле, вы могли бы попробовать это сами:

const test=[1,2,3,4,5]
test.length = 3
console.log(test) // [1,2,3]
test.length = 5
console.log(test) // guess what happens here!

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

В качестве дополнительного примечания, я немного сбит с толку тем, что ответ, получивший наибольшее количество голосов, продолжает распространять чрезмерно упрощенный миф (или полуправду) о том, что "все является объектом в JavaScript"; это не совсем так, в противном случае вы никогда не будете изучать примитивы, например.

Попробуйте сделать это:

const pippi = "pippi"
pippi.cat = "cat"
console.log(pippi.cat) // will it work? Throw an error? Guess why again

Спойлер:строка оборачивается в одноразовый объект для этой конкретной операции во второй строке, затем в следующей вы просто собираетесь получить доступ к свойству примитива, которого там нет (при условии, что вы не играли с String.prototype или что-то подобное), таким образом, вы получаете undefined.

Характеристики массива Javascript

  1. Динамический - массивы в Javascript могут расти динамически .push
  2. Может быть разреженным - Например,массив [50000] = 2;
  3. Может быть плотным - Например,массив =[1, 2, 3, 4, 5]

В Javascript среде выполнения трудно определить, будет ли массив плотным или разреженным.Так что все, что он может сделать, это сделать предположение.Все реализации используют эвристику, чтобы определить, является ли массив плотным или разреженным.Например, код в пункте 2 выше может указывать среде выполнения javascript, что это, скорее всего, реализация с разреженным массивом.Если массив инициализирован начальным числом, это может указывать на то, что это, скорее всего, плотный массив.

Когда среда выполнения обнаруживает, что массив разрежен, он реализуется аналогично объекту.Таким образом, вместо поддержания непрерывного массива создается карта ключ / значение.

Для получения дополнительной информации - https://www.quora.com/How-are-javascript-arrays-implemented-internally

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top