Remplacez une valeur si nulle ou indéfinie dans JavaScript


128

J'ai besoin d'appliquer l' ??opérateur C # à JavaScript et je ne sais pas comment. Considérez ceci en C #:

int i?=null;
int j=i ?? 10;//j is now 10

Maintenant, j'ai cette configuration en JavaScript:

var options={
       filters:{
          firstName:'abc'
       } 
    };
var filter=options.filters[0]||'';//should get 'abc' here, it doesn't happen
var filter2=options.filters[1]||'';//should get empty string here, because there is only one filter

Comment le faire correctement?

Merci.

EDIT: J'ai repéré la moitié du problème: je ne peux pas utiliser la notation «indexeur» pour les objets ( my_object[0]). Y a-t-il un moyen de le contourner? (Je ne connais pas les noms des propriétés des filtres à l'avance et je ne veux pas les parcourir).

Réponses:


271

Voici l'équivalent JavaScript:

var i = null;
var j = i || 10; //j is now 10

Notez que l' opérateur logique|| ne renvoie pas une valeur booléenne mais la première valeur qui peut être convertie en vrai .

Utilisez également un tableau d'objets au lieu d'un seul objet:

var options = {
    filters: [
        {
            name: 'firstName',
            value: 'abc'
        }
    ]
};
var filter  = options.filters[0] || '';  // is {name:'firstName', value:'abc'}
var filter2 = options.filters[1] || '';  // is ''

Cela peut être consulté par index.


57
Notez que cela ne fonctionne pas si 0 est une valeur valide de i.
jt000

13
Si quelque chose Falsey est une entrée potentiellement valide ( 0, false, chaîne vide), je ferais quelque chose comme ceci: Ce var j = (i === null) ? 10 : i;qui ne remplacera null, plutôt que tout ce qui peut être évalué à false.
DBS du

Y a-t-il un équivalent pour cela dans Groovy?
user6123723

si in'est pas défini, cela générera une erreur. me semble inutile ainsi .. (?)
phil294

@ phil294 var j = (i != null ? i : 10);devrait fonctionner, car undefinedest ==nul, tout i != nullcomme falsepour nullet undefined.
ToolmakerSteve

6

J'ai repéré la moitié du problème: je ne peux pas utiliser la notation «indexeur» pour les objets (mon_objet [0]). Y a-t-il un moyen de le contourner?

Non; un objet littéral, comme son nom l'indique, est un objet et non un tableau, vous ne pouvez donc pas simplement récupérer une propriété basée sur un index, car il n'y a pas d'ordre spécifique de leurs propriétés. La seule façon de récupérer leurs valeurs est d'utiliser le nom spécifique:

var someVar = options.filters.firstName; //Returns 'abc'

Ou en les parcourant en utilisant la for ... inboucle:

for(var p in options.filters) {
    var someVar = options.filters[p]; //Returns the property being iterated
}

1
@LinusGeffarth Notez que cette for inboucle JS amusante ne fonctionne que sur les littéraux d'objet! Il échoue lamentablement sur les tableaux JS (donne l'index) et JS Maps (donne undefined). J'espère que vous ne l'oubliez pas, de peur que vous n'ayez une surprise de débogage! xP
varun

4

Réponse ES2020

Le nouvel opérateur Nullish Coalescing est enfin disponible sur JavaScript, bien que la prise en charge du navigateur soit limitée. Selon les données de caniuse , seuls 48,34% des navigateurs sont pris en charge (en avril 2020).

Selon la documentation,

L'opérateur de fusion nul (??) est un opérateur logique qui renvoie son opérande de droite lorsque son opérande de gauche est nul ou indéfini, et renvoie autrement son opérande de gauche.

const options={
  filters:{
    firstName:'abc'
  } 
};
const filter = options.filters[0] ?? '';
const filter2 = options.filters[1] ?? '';

Cela garantira que vos deux variables auront une valeur de repli de ''if filters[0]ou filters[1]are null, ou undefined.

Notez que l'opérateur de fusion nullish ne renvoie pas la valeur par défaut pour les autres types de valeurs fausses telles que 0et ''. Si vous souhaitez tenir compte de toutes les valeurs fausses, vous devez utiliser l'opérateur OR ||.


0

Affectation logique nulle, solution 2020+

Un nouvel opérateur est actuellement ajouté aux navigateurs, ??=. C'est équivalent à value = value ?? defaultValue.

||=et &&=sont également à venir, liens ci-dessous.

Cela vérifie si le côté gauche est indéfini ou nul, court-circuitant s'il est déjà défini. Sinon, le côté gauche reçoit la valeur du côté droit.

Exemples de base

let a          // undefined
let b = null
let c = false

a ??= true  // true
b ??= true  // true
c ??= true  // false

// Equivalent to
a = a ?? true

Exemples d'objets / de tableaux

let x = ["foo"]
let y = { foo: "fizz" }

x[0] ??= "bar"  // "foo"
x[1] ??= "bar"  // "bar"

y.foo ??= "buzz"  // "fizz"
y.bar ??= "buzz"  // "buzz"

x  // Array [ "foo", "bar" ]
y  // Object { foo: "fizz", bar: "buzz" }

Exemple fonctionnel

function config(options) {
    options.duration ??= 100
    options.speed ??= 25
    return options
}

config({ duration: 555 })   // { duration: 555, speed: 25 }
config({})                  // { duration: 100, speed: 25 }
config({ duration: null })  // { duration: 100, speed: 25 }

?? = Support du navigateur juillet 2020 - .03%

?? = Documentation Mozilla

|| = Documentation Mozilla

&& = Documentation Mozilla


0

Solution de destruction

Le contenu de la question a peut-être changé, je vais donc essayer de répondre en profondeur.

La destruction vous permet d'extraire des valeurs de tout ce qui a des propriétés. Vous pouvez également définir des valeurs par défaut lorsque nul / non défini et des alias de nom.

const options = {
    filters : {
        firstName : "abc"
    } 
}

const {filters: {firstName = "John", lastName = "Smith"}} = options

// firstName = "abc"
// lastName = "Smith"

REMARQUE: la capitalisation est importante

Si vous travaillez avec un tableau, voici comment procéder.

Dans ce cas, le nom est extrait de chaque objet du tableau et reçoit son propre alias. Puisque l'objet pourrait ne pas exister = {}a également été ajouté.

const options = {
    filters: [{
        name: "abc",
        value: "lots"
    }]
}

const {filters:[{name : filter1 = "John"} = {}, {name : filter2 = "Smith"} = {}]} = options

// filter1 = "abc"
// filter2 = "Smith"

Tutoriel plus détaillé

Prise en charge du navigateur 92% juillet 2020

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.