Perché il 1 ° metodo map
qui sotto elabora l'elemento # 2 come undefined
ma il 2 ° metodo map
no?
const a = [undefined,,42]; // Note the two consecutive commas.
console.log(a.map(x=>x)); // -> [undefined, undefined, 42]
console.log(a.map(x=>x===undefined)); // -> [true, undefined, false]
Espandilo con il codice qui sotto. Lì ho alcuni esempi numerati che illustrano i miei punti. In ogni caso creo un array a 3 elementi e da quel momento sono interessato solo al secondo elemento. Dimostrò che questo 2 ° elemento può essere considerato come undefined
sia dal modo in cui risponde a .toString()
(cioè come appare in console.log(elmt2)
) sia come si comporta in una dichiarazione di uguaglianza (cioè elmt2 === undefined
?) . Quindi, tuttavia, associo tutti gli elementi dell'array a una stringa costante indipendentemente da quali siano i valori (ad esempio array.map(_=>'foo')
) e osserviamo il 2 ° elemento del risultato mappato. Mi sarei aspettato che tutte le uscite fossero la stringa costante, ma non lo sono.
const check = (i, array) => {
const mapped = array.map(() => 'mapped ');
const equalsUndefined = (array[1] === undefined);
const mappable = (array.map(_=>1)[1] === 1);
console.log('${i}: ${array[1]} ${equalsUndefined} ${mapped[1]} ${mappable}');
};
const uExplicit = [4, undefined, 4][1];
const uEmptySlot = [4, , 4][1];
const uNewArray = (new Array(3) )[1];
console.log('#: origValue =undef? mappedValue mappable?');
check(1, [4, undefined , 4]);
check(2, [4, , 4]);
check(3, new Array(3) );
check(4, [4, uExplicit , 4]);
check(5, [4, uEmptySlot, 4]);
check(6, [4, uNewArray , 4]);
/*
results:
#: origValue =undef? mappedValue mappable?
1: undefined true mapped true
2: undefined true undefined false
3: undefined true undefined false
4: undefined true mapped true
5: undefined true mapped true
6: undefined true mapped true
*/
La riga 1 mostra che un valore undefined
esplicito può essere mappato correttamente in questo modo.
Tuttavia, le righe 2 e amp; 3 mostrano che gli elementi dell'array che possono essere considerati "vuoti" non possono essere mappati correttamente, anche se si comportano come undefined
in base ai due test descritti sopra. Nella riga 2, il valore viene estratto da uno spazio vuoto letterale tra due elementi di matrice altrimenti normali. Nella riga 3, il valore viene estratto da una matrice creata utilizzando new Array(arrayLength)
.
Stranamente, righe 3, 4 e amp; 5 mostrano che i valori esaminati nelle righe 1, 2 e amp; 3 rispettivamente possono essere mappati correttamente se vengono assegnati prima a una variabile, invece di essere usati direttamente.
Per essere chiari, la documentazione MDN per gli array afferma che new Array(arrayLength)
crea "... una matrice di slot vuoti di arrayLength, non slot con valori non definiti reali". Tuttavia, l'output qui mostra che questi valori sono trattati come undefined
, almeno rispetto a come si comportano con .toString()
e in istruzioni di uguaglianza.
Quindi, ci sono due "sapori" diversi di undefined
in JavaScript, uno che può essere manipolato usando map
e uno che non può? Questo comportamento è previsto / benedetto (anche se è forse un po 'contro-intuitivo)? Esiste un modo sicuro per map
attraverso un array in modo che tutti i valori di undefined
possano essere trattati in modo identico?
UPDATE: THE SOURCE OF MY UNCERTAINTY
Ho scoperto perché ero perplesso. Si scopre che lo snippet di codice Stack Overflow produce un output ambiguo quando si utilizza console.log
in questo caso, il che mi fa pensare che qualcosa fosse undefined
quando in realtà era inesistente.
Per il semplice comando console.log([undefined,,4])
, le console di Chrome, Firefox, Safari e Opera producono output corretti e non ambigui:
Chrome:
Firefox:
Safari:
Opera:
Tuttavia,l'outputdallostrumentosnippetdicodicesuStackOverflow(inqualsiasibrowser)èambiguoealmenofuorviantesenontecnicamentenoncorretto(asecondadicomesidefiniscecosadovrebbefareconsole.log
).(AncheseallafinehopostatoquestadomandasuSoftwareEngineering,chenonhalostrumentosnippetdicodice,inizialmentehorisoltoilproblemasuStackOverflow,cosachemihaportatoavederel'outputconfusomostratodiseguito.)Devodividerel'inputel'outputindueimmaginiseparatesoloperchésitrovanosupartidiversedelloschermo...
Inputdellosnippetdicodicedellostackoverflow:
Outputdellosnippetdicodicedellostackoverflow:
Sinoticheinquestauscitailprimoeilsecondoelementosonomostratiidenticamente,cioècomeundefined
,incontrastocontuttiglioutputdellaconsoledelbrowsersopraiqualimostrailprimoelementocomeundefined
mal'elementonellasecondaposizionecomenon-existent.
Solopergliinteressidellepersone,notailseguentebuginInternetExplorer11quandoprovoamostrarelastessacosanellasuaconsole: