¿Hay un null
operador de acceso a propiedad seguro (propagación / existencia nula) en ES6 (ES2015 / JavaScript.next / Harmony) como ?.
en CoffeeScript, por ejemplo? ¿O está planeado para ES7?
var aThing = getSomething()
...
aThing = possiblyNull?.thing
Esto será más o menos como:
if (possiblyNull != null) aThing = possiblyNull.thing
Idealmente, la solución no debería asignar (incluso undefined
) a aThing
if possiblyNull
isnull
if( obj?.nested?.property?.value )
lugar deif( obj && obj.nested && obj.nested.property && obj.nested.property.value )
var appConfig = loadConfig(config, process.env); connect(appConfig.database);
aconnect(config)
. Puede pasar un objeto mucho más sencilloconnect
en lugar de pasar todo elconfig
objeto, puede utilizarconf.username
,conf.password
en lugar de intentar algo así comoconfig[process.env]?.database?.username
,config[process.env]?.database?.password
. Referencia: Ley de Demeter .loadConfig
el ejemplo anterior), puede hacer suposiciones sobre la existencia de propiedades y omitir la comprobación nula en innumerables áreas de su aplicación.Respuestas:
Actualización (2020-01-31): Parece que la gente todavía está encontrando esto, aquí está la historia actual:
Actualización (2017-08-01): si desea utilizar un complemento oficial, puede probar la compilación alfa de Babel 7 con la nueva transformación. Su experiencia puede ser diferente
https://www.npmjs.com/package/babel-plugin-transform-optional-chaining
Original :
Una característica que logra que se encuentra actualmente en la etapa 1: Encadenamiento opcional.
https://github.com/tc39/proposal-optional-chaining
Si quiere usarlo hoy, hay un complemento de Babel que lo logra.
https://github.com/davidyaha/ecmascript-optionals-proposal
fuente
street = user.address?.street
pondríastreet
en cualquier caso?Street
Creo que sería asignadoundefined
. Pero al menos no se trataría de acceder a propiedades indefinidas.=
, parece que eso no es compatible con la especificación oficial actualmente. github.com/tc39/proposal-optional-chaining#not-supportedNo es tan bueno como el? operador, pero para lograr un resultado similar podría hacer:
Desde
null
yundefined
son ambos Falsy valores ( ver esta referencia ), la propiedad después de que el&&
operador sólo se accede si el precedente que no nulo o sin definir.Alternativamente, podría escribir una función como esta:
Uso:
O, con un valor de reserva:
fuente
!(user && user.address && user.address.postcode)
:)foo && foo.bar && foo.bar.quux ...
en una base de código grande, esto es feo y agrega mucha complejidad que sería mejor evitar._get<T>(func: () => T, fallbackValue?: T) :T
user.address.postcode
no está definido,_try(() => user.address.postcode, "")
regresará enundefined
lugar de""
. Entonces el código_try(() => user.address.postcode, "").length
generará una excepción.No. Puede usar lodash # get o algo así para esto en JavaScript.
fuente
lodash.get
es ligeramente diferente en que obviamente no puede hacer una asignación condicional.Alternativa a la vainilla para un acceso seguro a la propiedad
La asignación condicional más concisa probablemente sería esta
fuente
possiblyNull
que no esté definido /null
?||=
(((a.b || {}).c || {}).d || {}).e
. Pero más preciso sería((((a || {}).b || {}).c || {}).d || {}).e
No, no hay operador de propagación nulo en ES6. Tendrá que ir con uno de los patrones conocidos .
Sin embargo, puede utilizar la desestructuración:Hay muchas discusiones (por ejemplo, esto ) para agregar dicho operador en ES7, pero ninguna realmente despegó.
fuente
aThing = possiblyNull.thing
null
. Tendría que proporcionar un valor predeterminado, más o menos como este patrón pero con una sintaxis más confusa.Yendo por la lista aquí , actualmente no hay una propuesta para agregar un recorrido seguro a Ecmascript. Entonces, no solo no hay una buena manera de hacer esto, sino que no se agregará en el futuro previsible.
fuente
fuente
Encadenamiento opcional
?.
y fusión nula??
Ahora puede usar directamente en
?.
línea para probar la existencia de forma segura. Todos los navegadores modernos lo admiten.??
se puede usar para establecer un valor predeterminado si no está definido o es nulo.Si existe una propiedad,
?.
pasa a la siguiente verificación o devuelve el valor válido. Cualquier falla provocará un cortocircuito y regresará de inmediatoundefined
.Para garantizar un valor definido predeterminado, puede usar
??
. Si necesita el primer valor verdadero, puede usarlo||
.Si no marca un caso, la propiedad del lado izquierdo debe existir. Si no, arrojará una excepción.
?.
Soporte de navegador : 78%, julio de 2020??
Soporte de navegador : 78%Documentación de Mozilla
-
Asignación nula lógica, solución 2020+
Actualmente se están agregando nuevos operadores a los navegadores
??=
,||=
y&&=
. No hacen exactamente lo que está buscando, pero podrían conducir al mismo resultado dependiendo del objetivo de su código.??=
comprueba si el lado izquierdo es indefinido o nulo, cortocircuito si ya está definido. Si no, al lado izquierdo se le asigna el valor del lado derecho.||=
y&&=
son similares, pero se basan en los operadores||
y&&
.Ejemplos básicos
Ejemplos de objeto / matriz
Soporte de navegador Julio 2020 - .03%
Documentación de Mozilla
fuente
?.
y??
, y una próxima solución detallada que puede funcionar para su situación. Probablemente la mejor solución actual sea simplemente haceraThing = possiblyNull?.thing ?? aThing
Un método seguro de obtención profunda parece un ajuste natural para underscore.js, pero el problema es evitar la programación de cadenas. Modificando la respuesta de @ Felipe para evitar la programación de cadenas (o al menos retrasa los casos límite a la persona que llama):
Ejemplo:
fuente
_.get(obj, array_or_dotstring)
obj.a.b.c
vsobj['a']['b']['c']
keys
vieneSé que esta es una pregunta de JavaScript, pero creo que Ruby maneja esto de todas las formas solicitadas, así que creo que es un punto de referencia relevante.
.&
,try
Y && tienen sus puntos fuertes y los peligros potenciales. Un gran descuido de esas opciones aquí: http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/TLDR; La conclusión es que Rubyistas
dig
es tanto más fácil en los ojos y una garantía más fuerte que un valor onull
se le asignará.Aquí hay una implementación simple en TypeScript:
Esto se puede utilizar para cualquier profundidad de anidamiento y funciones de manejo.
El
try
enfoque es igualmente agradable de leer en JS, como se muestra en las respuestas anteriores. Tampoco requiere bucles, lo cual es un inconveniente de esta implementación.fuente
Pensé que esta pregunta necesitaba un poco de actualización para 2018. Esto se puede hacer muy bien sin el uso de bibliotecas
Object.defineProperty()
y se puede usar de la siguiente manera:Considero que esto es seguro (y js-ético) debido a las definiciones
writeable
yenumerable
ahora disponibles para eldefineProperty
método deObject
, como se documenta en MDNdefinición de la función a continuación:
He reunido un jsBin con salida de consola para demostrar esto. Tenga en cuenta que en la versión jsBin también he agregado una excepción personalizada para valores vacíos. Esto es opcional, por lo que lo he dejado fuera de la definición mínima anterior.
Las mejoras son bienvenidas
fuente