2016-02-23 10 views
10

To tylko małe pytanie.Array.prototype.fill() z obiektem przekazuje referencje, a nie nową instancję.

byłem bawiąc się trochę i próbował instancji nową tablicę o długości x, gdzie wszystkie elementy tej tablicy, gdzie zainicjowana do wartości y

var arr = new Array(x).fill(y); 

Działa to dobrze, gdy wartość y jest coś inny niż obiekt. co oznacza, że ​​jest y jest obiektem, prawdziwe są następujące:

var arr = new Array(2).fill({}); 
arr[0] === arr[1]; //is true; 
arr[0].test = 'string'; 
arr[1].test === 'string'; //is also true; 

Czy istnieje jakiś sposób, aby stwierdzić, że nowy obiekt powinien być tworzone dla każdego elementu podczas korzystania z funkcji do wypełnienia? Czy powinienem po prostu przekształcić go w pętlę?

Z góry dziękuję!

Odpowiedz

16

Można najpierw fill tablica z dowolnej wartości (np undefined), a następnie będzie można użyć map:

var arr = new Array(2).fill().map(u => ({})); 
var arr = new Array(2).fill().map(Object); 
+0

Dzięki! Ma sens! –

+0

również 'Array.from ({length: 2}, u => ({}))' – Slai

4

Zaakceptowanych odpowiedź jest dobra, i będzie działać w 90% przypadków.

Ale jeśli robią wysokiej wydajności aplikacji JS, a jeśli pracujesz z dużymi/ogromnych tablic, Array.map (..) tworzy duży przeciążenie w obu - pamięć i wykorzystanie procesora, gdyż tworzy kopia tablicy.

polecam użyć klasycznego dla pętli:

a = new Array(ARRAY_SIZE); 
    for (var i = 0; i < ARRAY_SIZE; i++) { 
     a[i] = []; 
    } 

I badanego trzy alternatywy i got to:

  • Proponowane odpowiedzi (11x razy !!! wolniej):

    a = new Array(ARRAY_SIZE).fill().map(u => { return []; }); 
    
  • prostą pętlę (najszybciej)

    a = new Array(ARRAY_SIZE); 
    for (var i = 0; i < ARRAY_SIZE; i++) { 
        a[i] = []; 
    } 
    
  • forEach (2x czas wolniej)

    a = new Array(ARRAY_SIZE).fill(); 
    a.forEach((val, i) => { 
        a[i] = []; 
    }) 
    

PS. Użyłem this fiddle do testów.

Powiązane problemy