Existe um null
operador de acesso à propriedade -safe (propagação / existência nula) no ES6 (ES2015 / JavaScript.next / Harmony) como ?.
no CoffeeScript, por exemplo? Ou está planejado para o ES7?
var aThing = getSomething()
...
aThing = possiblyNull?.thing
Isso será mais ou menos como:
if (possiblyNull != null) aThing = possiblyNull.thing
Idealmente, a solução não deve atribuir (mesmo undefined
) a aThing
se possiblyNull
énull
if( obj?.nested?.property?.value )
vez deif( obj && obj.nested && obj.nested.property && obj.nested.property.value )
var appConfig = loadConfig(config, process.env); connect(appConfig.database);
comconnect(config)
. Você pode passar um objeto muito mais simplesconnect
em vez de passar todo oconfig
objeto, você pode usarconf.username
,conf.password
em vez de tentar algo comoconfig[process.env]?.database?.username
,config[process.env]?.database?.password
. Referência: Lei de Demeter .loadConfig
exemplo acima), você pode fazer suposições sobre a existência de propriedades e pular a verificação nula em inúmeras áreas do seu aplicativo.Respostas:
Atualização (2020-01-31): Parece que as pessoas ainda estão encontrando isso, aqui está a história atual:
Atualização (01/08/2017): Se você deseja usar um plug-in oficial, pode tentar a versão alfa do Babel 7 com a nova transformação. Sua milhagem pode variar
https://www.npmjs.com/package/babel-plugin-transform-optional-chaining
Original :
Um recurso que realiza o que está atualmente no estágio 1: encadeamento opcional.
https://github.com/tc39/proposal-optional-chaining
Se você quiser usá-lo hoje, existe um plugin Babel que realiza isso.
https://github.com/davidyaha/ecmascript-optionals-proposal
fonte
street = user.address?.street
definiriastreet
em qualquer caso?Street
Eu acho que seria atribuídoundefined
. Mas pelo menos não tentaria acessar propriedades indefinidas.=
, parece que isso não é suportado na especificação oficial atualmente. github.com/tc39/proposal-optional-chaining#not-supportedNão é tão bom quanto o. operador, mas para obter um resultado semelhante, você pode:
Como
null
eundefined
são ambos valores falsos ( consulte esta referência ), a propriedade após o&&
operador é acessada apenas se o precedente não for nula ou indefinida.Como alternativa, você pode escrever uma função como esta:
Uso:
Ou, com um valor de fallback:
fonte
!(user && user.address && user.address.postcode)
:)foo && foo.bar && foo.bar.quux ...
em uma grande base de código, isso é feio e acrescenta muita complexidade que você evitaria._get<T>(func: () => T, fallbackValue?: T) :T
user.address.postcode
for indefinido,_try(() => user.address.postcode, "")
retornará emundefined
vez de""
. Portanto, o código_try(() => user.address.postcode, "").length
gerará uma exceção.Não. Você pode usar lodash # get ou algo parecido para isso em JavaScript.
fonte
lodash.get
é um pouco diferente, pois obviamente não pode fazer uma atribuição condicional.Alternativa de baunilha para acesso seguro à propriedade
A atribuição condicional mais concisa provavelmente seria essa
fonte
possiblyNull
/ não esteja definido /null
?||=
(((a.b || {}).c || {}).d || {}).e
. Mas mais precisa seria((((a || {}).b || {}).c || {}).d || {}).e
Não, não há operador de propagação nulo no ES6. Você terá que seguir um dos padrões conhecidos .
Você pode usar a desestruturação, no entanto:Existem muitas discussões (por exemplo, isso ) para adicionar um operador no ES7, mas nenhuma realmente decolou.
fonte
aThing = possiblyNull.thing
null
. Você precisaria fornecer um valor padrão, muito parecido com esse padrão, mas com uma sintaxe mais confusa.Indo pela lista aqui , atualmente não há nenhuma proposta para adicionar uma travessia segura ao Ecmascript. Portanto, não apenas não há uma maneira agradável de fazer isso, mas não será adicionado em um futuro próximo.
fonte
fonte
Encadeamento opcional
?.
e coalescência nula??
Agora você pode usar diretamente
?.
inline para testar com segurança a existência. Todos os navegadores modernos são compatíveis.??
pode ser usado para definir um valor padrão se indefinido ou nulo.Se existir uma propriedade,
?.
prossiga para a próxima verificação ou retorne o valor válido. Qualquer falha irá imediatamente causar um curto-circuito e retornarundefined
.Para garantir um valor definido padrão, você pode usar
??
. Se você precisar do primeiro valor de verdade, poderá usar||
.Se você não verificar um caso, a propriedade do lado esquerdo deverá existir. Caso contrário, lançará uma exceção.
?.
Suporte do navegador - 78%, julho de 2020??
Suporte ao navegador - 78%Documentação Mozilla
-
Designação nula lógica, solução 2020+
Novos operadores estão sendo adicionados aos navegadores,
??=
,||=
e&&=
. Eles não fazem exatamente o que você está procurando, mas podem levar ao mesmo resultado, dependendo do objetivo do seu código.??=
verifica se o lado esquerdo está indefinido ou nulo, em curto-circuito, se já definido. Caso contrário, o lado esquerdo recebe o valor do lado direito.||=
e&&=
são semelhantes, mas com base no||
e&&
operadores.Exemplos básicos
Exemplos de objeto / matriz
Suporte para navegadores julho de 2020 - 0,03%
Documentação Mozilla
fonte
?.
e??
, e uma solução futura detalhada que pode funcionar para sua situação. Provavelmente, a melhor solução atual é apenas fazeraThing = possiblyNull?.thing ?? aThing
Um método deep get seguro parece um ajuste natural para o underscore.js, mas o problema é evitar a programação de strings. Modificando a resposta de @ Felipe para evitar a programação de strings (ou pelo menos empurra as bordas de volta ao chamador):
Exemplo:
fonte
_.get(obj, array_or_dotstring)
obj.a.b.c
vsobj['a']['b']['c']
keys
vem?Sei que essa é uma pergunta sobre JavaScript, mas acho que Ruby lida com isso de todas as formas solicitadas, então acho que é um ponto de referência relevante.
.&
,try
E && têm seus pontos fortes e potenciais armadilhas. Um excelente resumo dessas opções aqui: http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/TLDR; A conclusão dos rubiístas é que
dig
é mais fácil aos olhos e uma garantia mais forte de que um valor ounull
será atribuído.Aqui está uma implementação simples no TypeScript:
Isso pode ser usado para qualquer profundidade de aninhamento e manipula funções.
A
try
abordagem é igualmente agradável de ler em JS, como mostrado nas respostas anteriores. Também não requer loop, que é uma desvantagem desta implementação.fonte
Eu pensei que essa pergunta precisava de uma atualização para 2018. Isso pode ser feito sem a necessidade de bibliotecas
Object.defineProperty()
e pode ser usado da seguinte maneira:Considero isso seguro (e js-ético) por causa das definições
writeable
eenumerable
agora disponíveis para odefineProperty
método deObject
, conforme documentado no MDNdefinição da função abaixo:
Reuni um jsBin com a saída do console para demonstrar isso. Observe que na versão jsBin também adicionei uma exceção personalizada para valores vazios. Isso é opcional e, portanto, deixei de fora da definição mínima acima.
Melhorias são bem-vindas
fonte