JavaScript " new Array (n)" oraz " Array.prototyp.Mapa " Dziwnów

Obserwowałem to w Firefox-3.5.7/Firebug-1.5.3 i Firefox-3.6.16 / Firebug-1.6.2

Kiedy odpalę Firebug:

    >>> x = new Array(3)
    [undefined, undefined, undefined]
    >>> y = [undefined, undefined, undefined]
    [undefined, undefined, undefined]

    >>> x.constructor == y.constructor
    true

    >>> x.map(function(){ return 0; })
    [undefined, undefined, undefined]
    >>> y.map(function(){ return 0; })
    [0, 0, 0]
Co tu się dzieje? Czy to błąd, czy nie rozumiem jak używać new Array(3)?
Author: leaf, 2011-03-31

12 answers

Wygląda na to, że pierwszy przykład

x = new Array(3);

Tworzy tablicę z niezdefiniowanymi wskaźnikami.

A drugi tworzy tablicę ze wskaźnikami do 3 niezdefiniowanych obiektów, w tym przypadku wskaźniki nie są niezdefiniowane, tylko obiekty, do których wskazują.

y = [undefined, undefined, undefined]
// The following is not equivalent to the above, it's the same as new Array(3)
y = [,,,];

Ponieważ map jest uruchamiana w kontekście obiektów w tablicy, uważam, że pierwsza mapa w ogóle nie uruchamia funkcji, podczas gdy druga udaje się uruchomić.

 95
Author: David Mårtensson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-22 13:02:38

Miałem zadanie, w którym znałem tylko długość tablicy i musiałem przekształcić elementy. Chciałem zrobić coś takiego:

let arr = new Array(10).map((val,idx) => idx);

Aby szybko utworzyć tablicę taką jak:

[0,1,2,3,4,5,6,7,8,9]

Ale nie zadziałało, ponieważ: zobacz odpowiedź Jonatana Lonowskiego kilka odpowiedzi.

Rozwiązaniem może być wypełnienie pozycji tablicy dowolną wartością (nawet niezdefiniowaną) za pomocą Array.prototyp.wypełnij()

let arr = new Array(10).fill(undefined).map((val,idx) => idx);

console.log(new Array(10).fill(undefined).map((val, idx) => idx));

Update

Innym rozwiązaniem może być:

let arr = Array.apply(null, Array(10)).map((val, idx) => idx);

console.log(Array.apply(null, Array(10)).map((val, idx) => idx));
 70
Author: cstuncsik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-03 07:23:29

Z ES6, możesz zrobić [...Array(10)].map((a, b) => a) , szybko i łatwo!

 56
Author: Manuel Beaudru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-05 16:20:16

Tablice są różne. Różnica polega na tym, że new Array(3) tworzy tablicę o długości trzech, ale bez właściwości, podczas gdy [undefined, undefined, undefined] tworzy tablicę o długości trzech i trzech właściwościach zwanych "0"," 1 "i" 2", z których każda ma wartość undefined. Możesz zobaczyć różnicę używając operatora in:

"0" in new Array(3); // false
"0" in [undefined, undefined, undefined]; // true

Wynika to z nieco mylącego faktu, że jeśli spróbujesz uzyskać wartość nieistniejącej właściwości dowolnego natywnego obiektu w JavaScript, zwróci ona undefined (zamiast rzucać błąd, jak to się dzieje, gdy próbujesz odnieść się do nieistniejącej zmiennej), który jest taki sam jak ten, który otrzymujesz, jeśli właściwość została wcześniej wyraźnie ustawiona na undefined.

 14
Author: Tim Down,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-31 15:12:42

Ze strony MDC dla map:

[...] callback jest wywoływane tylko dla indeksów tablicy, które mają przypisaną wartość; [...]

[undefined] w rzeczywistości stosuje setter na indeksie (es) tak, że map będzie iterować, podczas gdy new Array(1) po prostu inicjalizuje indeks(es) z domyślną wartością undefined, więc map pomija go.

Uważam, że jest to takie samo dla wszystkich metod iteracji .

 13
Author: Jonathan Lonowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-31 14:47:10

Rozwiązanie ES6:

[...Array(10)]

Nie działa na maszynie (2.3), chociaż

 13
Author: Serge Intern,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-05 06:22:51

Myślę, że najlepszym sposobem, aby to wyjaśnić, jest spojrzenie na sposób, w jaki Chrome radzi sobie z tym.

>>> x = new Array(3)
[]
>>> x.length
3

Więc to, co się dzieje, to to, że new Array () zwraca pustą tablicę, która ma długość 3, ale nie ma wartości. Dlatego, gdy uruchomisz x.map na technicznie pustej tablicy, nie ma nic do Ustawienia.

Firefox po prostu "wypełnia" te puste miejsca undefined, mimo że nie ma wartości.

Nie sądzę, żeby to był błąd, tylko kiepski sposób na reprezentuję to, co się dzieje. Przypuszczam, że Chrome jest "bardziej poprawny", ponieważ pokazuje, że właściwie nic nie ma w tablicy.
 7
Author: helloandre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-31 18:26:00

W specyfikacji ECMAScript 6th edition.

new Array(3) zdefiniuj tylko właściwość length i nie Definiuj właściwości indeksu jak {length: 3}. zobacz https://www.ecma-international.org/ecma-262/6.0/index.html#sec-array-len Krok 9.

[undefined, undefined, undefined] zdefiniuje właściwości indeksu i właściwość length jak {0: undefined, 1: undefined, 2: undefined, length: 3}. Zobacz też https://www.ecma-international.org/ecma-262/6.0/index.html#sec-runtime-semantics-arrayaccumulation ElementList punkt 5.

Metody map, every, some, forEach, slice, reduce, reduceRight, filter of Array sprawdzi właściwość index przy pomocy wewnętrznej metody HasProperty, więc new Array(3).map(v => 1) nie wywoła wywołania zwrotnego.

Aby uzyskać więcej szczegółów, zobacz https://www.ecma-international.org/ecma-262/6.0/index.html#sec-array.prototype.map

Jak naprawić?

let a = new Array(3);
a.join('.').split('.').map(v => 1);

let a = new Array(3);
a.fill(1);

let a = new Array(3);
a.fill(undefined).map(v => 1);

let a = new Array(3);
[...a].map(v => 1);
 5
Author: wenshin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-05 06:10:00

Wpadłem na to. Z pewnością wygodne byłoby korzystanie z Array(n).map.

Array(3) daje mniej więcej {length: 3}

[undefined, undefined, undefined] tworzy właściwości numerowane:
{0: undefined, 1: undefined, 2: undefined, length: 3}.

Implementacja map() działa tylko na zdefiniowane właściwości.

 4
Author: Vezquex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-29 02:01:55

Nie pluskwa. Tak zdefiniowany jest konstruktor tablicy.

Z MDC:

Podczas określania pojedynczego parametru numerycznego za pomocą konstruktora tablicy, określa się początkową długość tablicy. Poniższy kod tworzy tablicę pięciu elementów:

var billingMethod = new Array(5);

Zachowanie konstruktora tablicy zależy od tego, czy pojedynczy parametr jest liczbą.

Metoda .map() zawiera tylko w iteracji elementy tablica, która ma jawnie przypisane wartości. Nawet jednoznaczne przypisanie undefined spowoduje, że wartość zostanie uznana za kwalifikującą się do włączenia do iteracji. Wydaje się to dziwne, ale zasadniczo jest to różnica między właściwością jawną undefined na obiekcie a brakującą właściwością:

var x = { }, y = { z: undefined };
if (x.z === y.z) // true

Obiekt x nie posiada właściwości o nazwie "z", a obiekt y tak. Jednak w obu przypadkach wydaje się, że "wartością" właściwości jest undefined. W tablicy sytuacja jest podobnie: wartość length domyślnie wykonuje przypisanie wartości do wszystkich elementów od zera do length - 1. Dlatego funkcja .map() nic nie zrobi (nie wywoła wywołania zwrotnego), gdy zostanie wywołana na nowo zbudowanej tablicy z konstruktorem tablicy i argumentem liczbowym.

 3
Author: Pointy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-18 15:18:03

Jeśli robisz to w celu łatwego wypełnienia tablicy wartościami, nie możesz użyć fill ze względu na obsługę przeglądarki i naprawdę nie chcesz robić pętli for, możesz również wykonać x = new Array(3).join(".").split(".").map(..., która da ci tablicę pustych łańcuchów.

Muszę powiedzieć, że dość brzydki, ale przynajmniej problem i intencja są dość jasno przedstawione.
 3
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-21 14:42:49

W Chrome, jeśli zrobię {[0] } dostaję [], więc zgaduję, że natknąłeś się na błąd przeglądarki.

 -1
Author: stef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-31 14:43:07