Existe-t-il un opérateur d'accès à la propriété null
- safe (propagation/existence nulle) dans ES6 (ES2015/JavaScript.next/Harmony) tel que?.
in CoffeeScript par exemple? Ou est-ce prévu pour ES7?
var aThing = getSomething()
...
aThing = possiblyNull?.thing
Ce sera à peu près comme:
if (possiblyNull != null) aThing = possiblyNull.thing
Idéalement, la solution ne devrait pas affecter (même undefined
) à aThing
si possiblyNull
est null
Fonctionnalité accomplie actuellement à l'étape 1: Chaînage facultatif.
https://github.com/tc39/proposal-optional-chaining
Si vous voulez l'utiliser aujourd'hui, il existe un plugin Babel qui accomplit cela.
https://github.com/davidyaha/ecmascript-optionals-proposal
Update (2017-08-01): Si vous souhaitez utiliser un plugin officiel, vous pouvez essayer la version alpha de Babel 7 avec la nouvelle transformation. Votre kilométrage peut varier
https://www.npmjs.com/package/babel-plugin-transform-optional-chaining
Ce n'est pas aussi gentil que le? opérateur, mais pour obtenir un résultat similaire, vous pouvez obtenir:
user && user.address && user.address.postcode
Puisque null
et undefined
sont tous les deux des valeurs falsy ( voir cette référence ), la propriété située après l'opérateur &&
est accessible uniquement si le précédent n'est ni nul ni indéfini.
Alternativement, vous pouvez écrire une fonction comme celle-ci:
function _try(func, fallbackValue) {
try {
var value = func();
return (value === null || value === undefined) ? fallbackValue : value;
} catch (e) {
return fallbackValue;
}
}
Usage:
_try(() => user.address.postcode) // return postcode or undefined
Ou, avec une valeur de repli:
_try(() => user.address.postcode, "none") // return postcode or a custom string
Non. Vous pouvez utiliser lodash # get ou quelque chose comme ça pour cela en JavaScript.
Alternative à la vanille pour un accès sécurisé à la propriété
(((a.b || {}).c || {}).d || {}).e
L’affectation conditionnelle la plus concise serait probablement la suivante:
try { b = a.b.c.d.e } catch(e) {}
En passant par la liste ici , il n’existe actuellement aucune proposition visant à ajouter le parcours en toute sécurité à Ecmascript. Donc, non seulement il n'y a pas de moyen agréable de faire cela, mais cela ne sera pas ajouté dans un avenir prévisible.
Je sais que c’est une question JavaScript, mais je pense que Ruby s’y emploie de toutes les manières demandées. Je pense donc que c’est un point de référence pertinent.
.&
, try
, et && ont leurs forces et leurs pièges potentiels. Voici un bon aperçu de ces options: http://mitrev.net/Ruby/2015/11/13/the-operator-in-Ruby/
TLDR; La conclusion des Rubyists est que Dig
est à la fois plus facile pour les yeux et plus sûr encore que une valeur ou null
soit attribuée.
Voici une simple implémentation dans TypeScript:
export function Dig(target: any, ...keys: Array<string>): any {
let digged = target
for (const key of keys) {
if (typeof digged === 'undefined') {
return undefined // can also return null or a default value
}
if (typeof key === 'function') {
digged = key(digged)
} else {
digged = digged[key]
}
}
return digged
}
Ceci peut être utilisé pour n’importe quelle profondeur d’imbrication et manipule des fonctions.
a = Dig(b, 'c', 'd', 'e');
foo = () => ({});
bar = Dig(a, foo, 'b', 'c')
L’approche try
est également agréable à lire dans JS, comme indiqué dans les réponses précédentes. Cela ne nécessite pas non plus de bouclage, ce qui est un inconvénient de cette implémentation.
Une méthode de récupération en profondeur sûre semble un choix naturel pour underscore.js, mais le problème est d’éviter la programmation par chaîne. Modifier la réponse de @ Felipe pour éviter la programmation de chaînes (ou au moins repousser les cas Edge à l'appelant):
function safeGet(obj, props) {
return (props.length==1) ? obj[keys[0]] :safeGet(obj[props[0]], props.slice(1))
}
Exemple:
var test = {
a: {
b: 'b property value',
c: { }
}
}
safeGet(test, ['a', 'b'])
safeGet(test, "a.b".split('.'))