В javascript я определяю такой массив
var arr = [1,2,3];
также я могу сделать
arr[-1] = 4;
Теперь, если я сделаю
arr = undefined;
Я также теряю ссылку на значение в arr [-1] .
Итак, для меня логически кажется, что arr [-1] также является частью arr .
Но когда я делаю следующее (без установки arr на undefined)
arr.length;
Возвращает 3, а не 4 ;
Итак, я хочу сказать, что если массивы можно использовать с отрицательными индексами, эти отрицательные индексы также должны быть частью их длины **. Я не знаю, может быть, я ошибаюсь, или мне может не хватать какого-то понятия о массивах.
javascript
arrays
me_digvijay
источник
источник
arr[1.5] = 1
и это тоже не влияет на длину. В спецификации языка очень четко указано, что влияет на длину. Возможно, вам это не нравится, но вы должны с этим жить. Либо так, либо создайте свой собственный конкурирующий язык и убедите людей перейти на него.var a = []; a['foo'] = 'baz'
но это не значит, что вам следует это делать; это явно противоречит всем условностям.Ответы:
Да, но не так, как вы думаете.
Вы можете присвоить массиву произвольные свойства (как и любой другой объект в JavaScript), что вы и делаете, когда «индексируете» массив в
-1
и присваиваете значение. Поскольку это не член массива, а просто произвольное свойство, вам не следует ожидатьlength
рассмотрения этого свойства.Другими словами, следующий код делает то же самое:
var arr = [1, 2, 3]; arr.cookies = 4; alert(arr.length) // 3;
источник
length
имущество.for
цикл от0
до.length
. Сделайте,console.dir(arr)
чтобы увидеть объект целиком. Кроме того, использование скобок для доступа к массивам не является характеристикой массивов, это неотъемлемая характеристика объектов (var obj = {foo: 'bar'}; obj.foo or obj['foo']
).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
единообразны в этом отношении.источник
var a = new Array(9)
,a
имеет длину 9 и совсем не содержит элементов.Array.slice()
метод должен это делать.String.slice()
Метод делает то же самое.Обратите внимание, что когда вы используете индекс позиции (или 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
Значения помещаются в массив только тогда, когда вы играете по правилам. Если вы этого не сделаете, они не будут приняты. Однако они принимаются в самом объекте Array, что относится практически ко всему в 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
Так опять же , это на на объекте , но не в в массиве .
Замечательный вопрос! Наверняка заставил меня задуматься.
источник
["Foo", "Bar"]
но["Foo", "Bar", -1: "Fizzbuzz"]
проверьте скрипку здесь . Как вы и писали, оно становится свойством с ключом -1, но определенно видно на выходе. В противном случае ваш ответ будет красивым и полным. Если вы измените, я снова проголосую за, мой голос против был резким, но не могу его удалить; время истекло.Если вы действительно хотите, чтобы в длину были включены отрицательные индексы и другие индексы, создайте функциональность самостоятельно:
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
источник
if(Number(key) != NaN) length++;
если вы хотите отфильтровать плавающие, добавьте&& key % 1 == 0
к условиюМассив - это просто особый вид объекта в JS. Есть специальный синтаксис, и это хорошо, потому что позволяет эффективно с ними работать. Представьте, насколько утомительно было бы писать таким образом литерал массива:
const array = {0: 'foo', 1: 'bar', 2: 'baz'} //etc...
Но тем не менее они остаются объектами . Итак, если вы это сделаете:
const myArray = [42, 'foo', 'bar', 'baz']; myArray[-1] = 'I am not here'; myArray['whatever'] = 'Hello World';
Эти нецелочисленные свойства будут прикреплены к объекту (какому массиву), но они недоступны для некоторых собственных методов, таких как
Array.length
.Вы можете предположить, что собственный метод length - это геттер, который подсчитывает все свойства (а индексы - это свойства, а значения - фактические значения ), конвертируемые в положительное целое число или ноль. Что-то вроде этой псевдо-реализации:Согласно спецификациям , собственный
length
метод - как getter (exampleArray.length
) - будет проверять все неотрицательные целые числа меньше 2 32 » ключей, получать наибольший из них и возвращать его числовое значение + 1.Как setter (
exampleArray.length = 42
), он либо создаст несколько пустых слотов для `` отсутствующих '' индексов, если заданная длина больше, чем фактическое количество неотрицательных целочисленных ключей, либо удалит все неотрицательные целочисленные ключи (и их значения), которые не превышают заданная длина.Псевдо-реализация:
const myArray = { '-1': 'I am not here', // I have to use apostrophes to avoid syntax error 0: 42, 1: 'foo', 2: 'bar', 3: 'baz', whatever: 'Hello World', get myLength() { let highestIndex = -1; for (let key in this) { let toInt = parseInt(key, 10); if (!Number.isNaN(toInt) && toInt > -1) { // If you're not an integer, that's not your business! Back off! if (toInt > highestIndex) highestIndex = toInt; } } return highestIndex + 1; }, set myLength(newLength) { /* This setter would either: 1) create some empty slots for 'missing' indices if the given length is greater than the actual number of non-negative-integer keys 2) delete all non-negative-integer keys (and their values) which are not greater then the given length. */ } } console.log(myArray.myLength); // 4 myArray[9] = 'foobar'; console.log(myArray.myLength); // 10
источник
Массивы в JavaScript на самом деле являются объектами. Их просто прототипируют из конструктора Array.
Индексы массивов на самом деле являются ключами в хэш-карте, и все ключи преобразуются в строки. Вы можете создать любой ключ (например, «-1»), но методы в массиве настроены так, чтобы действовать как массив. Так что
length
это не размер объекта, он скорее гарантированно больше, чем наибольший целочисленный индекс. Точно так же при печатиarr
будут перечислены только значения с целыми ключами> = 0.Больше информации здесь.
источник
Согласно MDN:
В Javascript вы можете установить свойство для любого создаваемого вами объекта.
var array = new Array(); array = [1,2,3]; array["boom"] = "pow";
Таким же образом, когда вы устанавливаете отрицательный индекс, он сохраняет его как свойство массива, а не как часть индекса.
array[-1] = "property does not add to array length";
Вот почему длина не отражает это, а цикл for..in показывает это.
источник
Когда вы используете неположительные или нечисловые индексы, массив ведет себя как ассоциативный массив, который имеет пары ключ-значение.
Для итерации по массиву вы можете использовать
for(var index in myArray) { document.write( index + " : " + myArray[index] + "<br />"); }
источник