Как интерпретировать индексы массивов с плавающей точкой?
Я не могу найти никакой информации об этом, но предположим, что у меня есть
var arr = [1, 2, 3];
var x = arr[1.5];
Я предположил, что Javascript будет floor
индексом и возвращает элемент в индексе 1, но, кажется, по крайней мере в Chrome он просто возвращает undefined
.
Это правильно? Я не могу найти какой-либо стандарт или документацию, подтверждающую это. На самом деле это действительно неудобно, потому что я предположил, что поведение округления позволяет вам передать любой float в диапазоне [0, n) в индекс массива, но, похоже, вы будете тихо разбивать свои массивы, если вы делаете математику с плавающей запятой, которая не округляется.
Изменить: если кто-либо, поддерживающий список javascript файлов, добавляет этот. Теперь мне нужно просмотреть 10k строк кода javascript, чтобы узнать, где это допущение, которое я сделал, тихо вызывает ошибки!
Ответы
Ответ 1
Согласно MDN: Array, элементы массива на самом деле являются свойствами, а свойства идентифицируются по строкам.
Доступ к arr[1.5]
таким же образом, как и при доступе к arr['1.5']
, и Firefox действительно делает это таким образом.
Этот код:
var x = [0,1,2,3,4,5];
x[1.5] = 42;
alert(x);
alert(x['1.5']);
alert(x['1.50']);
выходы:
0, 1, 2, 3, 4, 5
42
undefined
Таким образом, элемент, доступ к которому осуществляется с использованием значения с плавающей запятой, является свойством, идентифицированным строковым представлением числа. Обратите внимание, что доступ к элементу с помощью '1.50'
не совпадает с доступом к элементу с помощью '1.5'
, поэтому индекс не преобразуется в число.
Я тестировал это и в Internet Explorer, и в Chrome, и оба они делают то же, что и Firefox.
Ответ 2
Это ожидалось, поскольку js преобразует индекс в строку и обращается к свойству объекта (поскольку индексы свойств объекта всегда являются строками), поэтому он действительно ищет arr['1.5']
Для неверующих соответствующая часть стандарта составляет 15.4, которая четко определяет индекс массива в виде строки.
Ответ 3
Я не знаю, почему вы считаете, что Chrome будет "округлять" или "наполнить" значение при доступе к Array
, но он этого не делает вообще. Также Firefox. Он просто обращается к "ключу", которого нет, и оба браузера корректно возвращают значение undefined
(по крайней мере, в последних версиях, которые я тестирую).
Поскольку Arrays
также Objects
в ECMAscript, вы просто получаете доступ к значению за ключом 1.5
.
Я действительно думаю, что я должен указать на это немного больше. Array
- это просто Object
(он также наследует от Object
) с свойством .length
и несколькими добавленными методами. Нет числового доступа к массиву, как в C/С++. Его просто доступ к ключевому названию объекта.
var foo = [1,2,3];
foo instanceof Array; // true;
foo instanceof Object; // true;
Ответ 4
var arr = [];
arr[0] = "hello";
alert(arr["0"]);
Output : hello
В JavaScript при индексировании элемента массива индекс преобразуется интерпретатором JavaScript в строку, которую он затем использует в качестве ключа. Это то же самое, что использовать хэш-карту пары ключ-значение в java.
arr[5-"5"]
В этом случае сначала вычисляется математическое выражение, и результат преобразуется в строку и используется в качестве ключа. Вот как это работает:
< 1 > Интерпретатор преобразует "5" в целое число, так как оператор "-" не может использоваться со строками, а затем вычитает его из левого операнда 5, чтобы получить результат 0.
< 2 > Результат затем преобразуется в строку и используется как ключ.