W javascript definiuję taką tablicę
var arr = [1,2,3];
też mogę
arr[-1] = 4;
Teraz, jeśli to zrobię
arr = undefined;
Tracę również odniesienie do wartości przy arr [-1] .
Więc logicznie wydaje mi się, że arr [-1] jest również częścią arr .
Ale kiedy śledzę (bez ustawiania arr na niezdefiniowane)
arr.length;
Zwraca 3 zamiast 4 ;
Chodzi mi więc o to, że jeśli tablice mogą być używane z indeksami ujemnymi, te indeksy ujemne również powinny być częścią ich długości **. Nie wiem, może się mylę lub może mi brakuje jakiegoś pojęcia o tablicach.
javascript
arrays
me_digvijay
źródło
źródło
arr[1.5] = 1
i to też nie wpływa na długość. Specyfikacja języka jasno określa, co wpływa na długość. Może ci się to nie podobać, ale musisz z tym żyć. Albo to, albo zaprojektuj własny, konkurencyjny język i przekonaj ludzi, aby na niego przeszli.var a = []; a['foo'] = 'baz'
ale to nie znaczy, że powinieneś; jest to wyraźnie sprzeczne ze wszystkimi konwencjami.Odpowiedzi:
Tak, ale nie w taki sposób, w jaki myślisz.
Możesz przypisać dowolne właściwości do tablicy (tak jak każdy inny obiekt w JavaScript), co robisz, gdy „indeksujesz” tablicę
-1
i przypisujesz jej wartość. Ponieważ nie jest to element tablicy, a jedynie dowolna właściwość, nie należy się spodziewaćlength
rozważania tej właściwości.Innymi słowy, poniższy kod robi to samo:
var arr = [1, 2, 3]; arr.cookies = 4; alert(arr.length) // 3;
źródło
length
własność.for
pętlę od0
do.length
. Zrób,console.dir(arr)
aby zobaczyć cały obiekt. Ponadto używanie notacji nawiasów do uzyskiwania dostępu do tablic nie jest charakterystyczne dla tablic, jest nieodłączną cechą obiektów (var obj = {foo: 'bar'}; obj.foo or obj['foo']
).length
Nieruchomość wróci numer o jeden wyższy od najwyższego przypisanego „Index”, gdzie Array „indeksy” są liczbami całkowitymi większa lub równa zeru. Zwróć uwagę, że JS zezwala na „rzadkie” tablice:var someArray = []; someArray[10] = "whatever"; console.log(someArray.length); // "11"
Oczywiście, jeśli nie ma elementów, to
length
jest0
. Zauważ również, żelength
nie zostanie zaktualizowany, jeśli użyjeszdelete
do usunięcia najwyższego elementu.Ale tablice są obiektami, więc możesz przypisywać właściwości z innymi dowolnymi nazwami właściwości, w tym liczbami ujemnymi lub ułamkami:
someArray[-1] = "A property"; someArray[3.1415] = "Vaguely Pi"; someArray["test"] = "Whatever";
Zauważ, że za kulisami JS konwertuje nazwy właściwości na łańcuchy, nawet jeśli podasz liczbę, taką jak
-1
. (Indeksy dodatnich liczb całkowitych również stają się łańcuchami).Metody tablicowe, takie jak
.pop()
,.slice()
itp., Działają tylko na zerowych lub wyższych liczbach całkowitych „indeksach”, a nie na innych właściwościach, więclength
są spójne w tym punkcie.źródło
var a = new Array(9)
,a
ma długość 9 i nie ma żadnych elementów.Array.slice()
metoda ma to zrobić.String.slice()
Metoda robi to samo.Zwróć uwagę, że gdy używasz indeksu pozycji (lub 0), wartości są umieszczane w tablicy:
var array = []; array[0] = "Foo"; array[1] = "Bar"; // Result: ["Foo", "Bar"] // Length: 2
Nie dzieje się tak, gdy dodajesz wartości bez indeksu (nie 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
Wartości są umieszczane w tablicy tylko wtedy, gdy grasz zgodnie z zasadami. Jeśli tego nie zrobisz, nie zostaną zaakceptowani. Są jednak akceptowane w samym obiekcie Array, co ma miejsce w przypadku prawie wszystkiego w JavaScript. Mimo że
["Foo", "Bar"]
są to jedyne wartości w naszej tablicy, nadal możemy uzyskać dostęp"Fizzbuzz"
:array[-1]; // "Fizzbuzz"
Ale zauważ jeszcze raz, że nie jest to część wartości tablicy, ponieważ jej „indeks” jest nieprawidłowy. Zamiast tego został dodany do tablicy jako kolejny element członkowski. Moglibyśmy uzyskać dostęp do innych elementów tablicy w ten sam sposób:
array["pop"]; // function pop() { [native code] }
Zauważ tutaj, że uzyskujemy dostęp do
pop
metody w tablicy, która informuje nas, że zawiera kod natywny. Nie uzyskujemy dostępu do żadnej z wartości tablicy za pomocą klucza „pop”, ale raczej do elementu członkowskiego samego obiektu tablicy. Możemy to dodatkowo potwierdzić, jadąc na rowerze po publicznych członkach obiektu:for (var prop in array) console.log(prop, array[prop]);
Który wypluwa:
0 Foo 1 Bar -1 Fizzbuzz
Więc jeszcze raz, to na tym obiekcie , ale to nie jest w tej tablicy .
Świetne pytanie! Na pewno sprawiło, że zrobiłem podwójną próbę.
źródło
["Foo", "Bar"]
ale["Foo", "Bar", -1: "Fizzbuzz"]
sprawdź tutaj skrzypce . Tak jak napisałeś, staje się właściwością z kluczem -1, ale jest to zdecydowanie widoczne na wyjściu. W przeciwnym razie twoja odpowiedź jest ładna i kompletna. Jeśli się zmienisz, ponownie zagłosuję za, mój głos był ostry, ale nie mogę go usunąć; czas minął.Jeśli naprawdę chcesz, aby indeksy ujemne i inne indeksy były uwzględnione w długości, utwórz tę funkcjonalność samodzielnie:
function getExtendedArray() { var a = []; Object.defineProperty(a, 'totalLength', { get : function() { return Object.keys(a).length; } }); return a; }
Wtedy na przykład:
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
źródło
if(Number(key) != NaN) length++;
Jeśli chcesz odfiltrować zmiennoprzecinkowe, dodaj&& key % 1 == 0
do warunkuTablica to po prostu specjalny rodzaj obiektu w JS. Istnieje specjalna składnia, która jest dobra, ponieważ pozwala nam efektywnie z nimi pracować. Wyobraź sobie, jak żmudne byłoby pisanie literału tablicowego w ten sposób:
const array = {0: 'foo', 1: 'bar', 2: 'baz'} //etc...
Niemniej jednak nadal są obiektami . Więc jeśli to zrobisz:
const myArray = [42, 'foo', 'bar', 'baz']; myArray[-1] = 'I am not here'; myArray['whatever'] = 'Hello World';
Te nie-całkowite właściwości zostaną dołączone do obiektu (którym jest tablica), ale nie są dostępne dla niektórych metod natywnych, takich jak
Array.length
.Można założyć, że natywna metoda „length” jest metodą pobierającą, która zlicza wszystkie właściwości (a indeksy są właściwościami, a wartości są wartościami rzeczywistymi ), które można zamienić na dodatnią liczbę całkowitą lub zero. Coś takiego jak ta pseudo-implementacja:Ze względu na specyfikacje
length
metoda natywna - jako metoda pobierająca (exampleArray.length
) - sprawdzi wszystkie nieujemne liczby całkowite mniejsze niż 2 32 klucze ”, największy z nich i zwróci jego wartość numeryczną + 1.Jako setter (
exampleArray.length = 42
), utworzy kilka pustych pozycji dla `` brakujących '' indeksów, jeśli dana długość jest większa niż rzeczywista liczba nieujemnych kluczy całkowitych, lub usunie wszystkie nieujemne klucze całkowite (i ich wartości), które nie są większe niż podana długość.Pseudo-implementacja:
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
źródło
Tablice w JavaScript są w rzeczywistości obiektami. Są po prostu prototypowane z konstruktora Array.
Indeksy tablicowe są w rzeczywistości kluczami w tablicy mieszającej, a wszystkie klucze są konwertowane na ciągi. Możesz utworzyć dowolny klucz (np. „-1”), ale metody w Array są dostosowane do działania jak tablica. Tak więc
length
nie jest to rozmiar obiektu, a jedynie gwarantuje, że będzie większy niż największy indeks całkowity. Podobnie, drukowaniearr
wyświetli tylko wartości z kluczami całkowitymi> = 0.Więcej informacji tutaj.
źródło
Według MDN:
W Javascript możesz ustawić właściwość dowolnego tworzonego obiektu.
var array = new Array(); array = [1,2,3]; array["boom"] = "pow";
W ten sam sposób, gdy ustawisz indeks ujemny, zapisuje go jako właściwość w tablicy, a nie jako część indeksu.
array[-1] = "property does not add to array length";
Dlatego długość nie odzwierciedla tego, ale pokazuje to pętla for..in.
źródło
W przypadku korzystania z indeksów niepozytywnych lub nieliczbowych tablica zachowuje się jak tablica asocjacyjna zawierająca pary klucz-wartość.
Aby iterować po tablicy, której możesz użyć
for(var index in myArray) { document.write( index + " : " + myArray[index] + "<br />"); }
źródło