Esta es una pregunta de seguimiento que hice incidentalmente al final de ¿Por qué el compilador de TypeScript compila sus operadores opcionales de encadenamiento y fusión nula con dos comprobaciones? Como señaló jcalz , la leyenda residente de TypeScript, en un comentario, merece su propia pregunta.
// Why does the JavaScript treat x?.y // as x === null || x === void 0 ? void 0 : xy // instead of x === null || x === void 0 ? x : xy // ? Cuando x == null , este último conservaría null mientras que el primero siempre devuelve undefined .
Soporte de navegadores modernos ?. de forma nativa, para que podamos probar este comportamiento.
const test = () => { console.log('undefined?.x\t\t==>\t', undefined?.x); console.log('null?.x\t\t\t==>\t', null?.x); console.log('null?.x === null\t==>\t', null?.x === null); }; try { eval('null?.x'); test(); } catch { console.error('Your browser does not support optional chaining syntax.'); console.info('While optional chaining is supported by all modern browsers, this will not work in browsers that do not support the syntax.') console.warn('😮'); console.info('Shocking, I know.'); console.info('Compatibility chart: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining#browser_compatibility'); }En las preguntas frecuentes sobre la propuesta de encadenamiento opcional , dice:
¿Por qué
(null)?.bse evalúa comoundefineden lugar denull?Ni
abnia?.bpretenden preservar información arbitraria sobre el objeto basea, sino solo brindar información sobre la propiedad"b"de ese objeto. Si una propiedad"b"está ausente dea, esto se refleja enab === undefinedya?.b === undefined. En particular, se considera que el valornullno tiene propiedades; por lo tanto,(null)?.bno está definido.
Así que esa parece ser la respuesta pública prevista a esta pregunta. La propiedad no existe, por lo que el encadenamiento opcional le brinda el comportamiento normal para leer propiedades inexistentes ( undefined ) sin que tenga que preocuparse por generar un TypeError .
Por supuesto, usted no es el único que espera que a?.b .b debería propagar la nulidad de a en su lugar. Existe un debate bastante animado sobre qué (null)?.b debería estar en los números (ahora cerrados) tc39/proposal-opcional-chaining#65 y tc39/proposal-opcional-chaining#69 .
En tc39/poc#65 vemos que se realizó una encuesta de reddit y el consenso favoreció "siempre undefined " sobre "a veces null ". Y en tc39/poc#69 alguien hizo una encuesta de bibliotecas JS que tenían versiones de funciones de este tipo de operador como la property de Undercore y get de Lodash , y preguntó: "if someLibraryFunction({a: 123}, "a") produce 123 , y someLibraryFunction(undefined, "a") produce undefined , ¿qué produce someLibraryFunction(null, "a") ? Parece que la respuesta no está undefined para la mayoría de las bibliotecas consultadas.
Ninguno de ellos es necesariamente una razón definitiva por la que tenemos undefined en lugar de null . Pero indican que las fuerzas de undefined parecen haber tenido algo más de poder o resistencia que las fuerzas de null y que finalmente prevaleció undefined , siempre volviendo al argumento de que "se supone que a a?.b te permite leer la propiedad b de a sin preocuparse por TypeError ".