Должны ли отрицательные индексы в массивах JavaScript способствовать длине массива?
в javascript я определяю такой массив
var arr = [1,2,3];
также я могу сделать
arr[-1] = 4;
теперь, если я делаю
arr = undefined;
Я также теряю ссылку на значение в arr[-1].
поэтому для меня логически кажется, что arr[-1] также является частью arr.
но когда я делаю следующее (без установки arr в undefined)
arr.length;
возвращает 3 не 4;
так что моя точка зрения если массивы могут быть использованы с отрицательными индексами, эти отрицательные индексы также должны быть частью их длины**.
Я не знаю, может быть, я ошибаюсь или мне может не хватать какой-то концепции о массивах.
7 ответов:
поэтому для меня логически кажется, что arr[-1] также является частью arr.
да, но не так, как вы думаете.
вы можете назначить произвольные свойства массиву (как и любой другой объект в JavaScript), что вы и делаете, когда вы "индексируете" массив в
-1и присвоить значение. Поскольку это не член массива, а просто произвольное свойство, вы не должны ожидатьlengthучитывать, что свойство.другими словами, следующий код делает то же самое:
var arr = [1, 2, 3]; arr.cookies = 4; alert(arr.length);
The
lengthсвойство вернет номер один выше, чем самый высокий назначенный "индекс", где массив "индексы" являются целыми числами, большими или равными нулю. Обратите внимание, что JS позволяет" разреженные " массивы:var someArray = []; someArray[10] = "whatever"; console.log(someArray.length); // "11"конечно, если нет элементов, то
lengthи0. Обратите внимание также, чтоlengthне обновляется, если вы используетеdeleteудалить наибольший элемент.но массивы являются объектами, поэтому вы можете назначать свойства с другим произвольным свойством имена, включая отрицательные числа или дроби:
someArray[-1] = "A property"; someArray[3.1415] = "Vaguely Pi"; someArray["test"] = "Whatever";обратите внимание, что за кулисами JS преобразует имена свойств в строки, даже если вы указываете число, например
-1. (Положительные целочисленные индексы также становятся строками, если на то пошло.)методы массива, например
.pop(),.slice()и т. д., работают только с нулевыми или более высокими целыми "индексами", а не с другими свойствами, поэтомуlengthявляется последовательным в этом вопросе.
обратите внимание, что при использовании индекса позиции (или 0) значения помещаются в массив:
var array = []; array[0] = "Foo"; array[1] = "Bar"; // Result: ["Foo", "Bar"] // Length: 2это не тот случай, когда вы добавляете неиндексные значения (не 0-9+):
var array = []; array[0] = "Foo"; array[1] = "Bar"; array[-1] = "Fizzbuzz"; // Not a proper array index - kill it // Result: ["Foo", "Bar"] // Length: 2значения помещаются в массив только тогда, когда вы играете по правилам. Когда вы этого не делаете, они не принимаются. Однако они принимаются на самом объекте массива, что имеет место практически со всем в JavaScript. Даже если
["Foo", "Bar"]единственные ценности в наше время, мы все еще можем доступ"Fizzbuzz":array[-1]; // "Fizzbuzz"но обратите внимание еще раз, что это не является частью значений массива, так как его "индекс" не является допустимым. Вместо этого он был добавлен в массив как еще один член. Мы могли бы получить доступ к другим членам массива таким же образом:
array["pop"]; // function pop() { [native code] }обратите внимание, что мы обращаемся к
popметод на массиве, который сообщает нам, что это содержит собственный код. Мы не обращаемся ни к одному из значений массива с ключом "pop", а скорее к члену объекта массива себя. Мы можем дополнительно подтвердить это, проехав на велосипеде по публичным членам объекта:for (var prop in array) console.log(prop, array[prop]);, который выплевывает следующее:
0 Foo 1 Bar -1 Fizzbuzzтак опять же, это on the объект, но не на the массив.
удивительный вопрос! Заставил меня сделать два точно.
Если вы действительно хотите, чтобы отрицательные индексы и другие индексы были включены в длину, то создайте функциональность самостоятельно:
function getExtendedArray() { var a = []; Object.defineProperty(a, 'totalLength', { get : function() { return Object.keys(a).length; } }); return a; }потом например:
var myArray = getExtendedArray(); console.log(myArray.totalLength); // 0 myArray.push("asdf"); myArray[-2] = "some string"; myArray[1.7777] = "other string"; console.log(myArray.totalLength); // 3
массивы в JavaScript на самом деле являются объектами. Они просто прототип из конструктора массива.
индексы массива на самом деле являются ключами в хэш-карте, и все ключи преобразуются в строки. Вы можете создать любой ключ (т. е. "-1"), но методы на массиве адаптированы, чтобы действовать как массив. Так что
lengthЭто не размер объекта, это скорее только гарантированно будет больше, чем самый большой целочисленный индекс. Аналогично, печатьarrбудет только список значений с целочисленными ключами >= 0.
согласно MDN:
значение свойства length является целым числом с положительным знаком и значением меньше 2 в 32 степени (232)
в Javascript можно задать свойство для любого создаваемого объекта.
var array = new Array(); array = [1,2,3]; array["boom"] = "pow";точно так же, когда вы устанавливаете отрицательный индекс, он сохраняет его как свойство в массиве, а не часть индекса.
array[-1] = "property does not add to array length";вот почему длина не отражает его, но a for..in петля показывает оно.
при использовании неположительных или нечисловых индексов массив ведет себя как ассоциативный массив, который имеет пары ключ-значение.
для перебора массива можно использовать
for(var index in myArray) { document.write( index + " : " + myArray[index] + "<br />"); }
Comments