Sostituisci un valore se nullo o non definito in JavaScript


128

Ho un requisito per applicare l' ??operatore C # a JavaScript e non so come. Considera questo in C #:

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

Ora ho questa configurazione in 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

Come lo faccio correttamente?

Grazie.

EDIT: ho individuato metà del problema: non posso usare la notazione "indicizzatore" per gli oggetti ( my_object[0]). C'è un modo per aggirarlo? (Non conosco i nomi delle proprietà dei filtri in anticipo e non voglio iterarli su di essi).

Risposte:


271

Ecco l'equivalente JavaScript:

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

Notare che l' operatore logico|| non restituisce un valore booleano ma il primo valore che può essere convertito in vero .

Inoltre, utilizza un array di oggetti invece di un singolo oggetto:

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

È possibile accedervi da index.


57
Nota che questo non funziona se 0 è un valore valido di i.
jt000

13
Semmai Falsey è un ingresso potenzialmente valido ( 0, false, stringa vuota), vorrei fare qualcosa di simile, invece: var j = (i === null) ? 10 : i;che non farà che sostituire null, piuttosto che tutto ciò che può essere valutato per falso.
DBS

C'è un equivalente per questo in Groovy?
user6123723

se inon è definito, verrà generato un errore. mi sembra inutile così .. (?)
phil294

@ phil294 var j = (i != null ? i : 10);dovrebbe funzionare, perché undefinedè ==nullo, così i != nullè falseper entrambi nulle undefined.
ToolmakerSteve

6

Ho individuato metà del problema: non riesco a utilizzare la notazione "indicizzatore" per gli oggetti (mio_oggetto [0]). C'è un modo per aggirarlo?

No; un oggetto letterale, come suggerisce il nome, è un oggetto e non un array, quindi non è possibile recuperare semplicemente una proprietà in base a un indice, poiché non esiste un ordine specifico delle loro proprietà. L'unico modo per recuperare i loro valori è utilizzare il nome specifico:

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

O iterando su di essi usando il for ... inciclo:

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

1
@LinusGeffarth Nota che questo divertente for inciclo JS funziona solo su oggetti letterali! Fallisce miseramente su array JS (dà indice) e JS Maps (dà undefined). Spero che non te lo dimentichi, per non avere una sorpresa per il debug! xP
varun

4

Risposta ES2020

Il nuovo Nullish Coalescing Operator, è finalmente disponibile su JavaScript, sebbene il supporto del browser sia limitato. Secondo i dati di caniuse , solo il 48,34% dei browser è supportato (ad aprile 2020).

Secondo la documentazione,

L'operatore di coalescenza nullo (??) è un operatore logico che restituisce il suo operando di destra quando il suo operando di sinistra è nullo o non definito e restituisce altrimenti il ​​suo operando di sinistra.

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

Ciò garantirà che entrambe le variabili avranno un valore di riserva di ''if filters[0]o filters[1]are null, o undefined.

Si noti che l'operatore di coalescenza nullo non restituisce il valore predefinito per altri tipi di valore falso come 0e ''. Se desideri tenere conto di tutti i valori falsi, dovresti utilizzare l'operatore OR ||.


0

Assegnazione logica nullo, soluzione 2020+

Un nuovo operatore è in fase di aggiunta ai browser, ??=. Questo è equivalente a value = value ?? defaultValue.

||=e &&=stanno arrivando anche, link sotto.

Controlla se il lato sinistro è indefinito o nullo, cortocircuito se già definito. In caso contrario, al lato sinistro viene assegnato il valore del lato destro.

Esempi di base

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

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

// Equivalent to
a = a ?? true

Esempi di oggetti / array

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" }

Esempio funzionale

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 }

?? = Supporto browser luglio 2020 - 0,03%

?? = Documentazione Mozilla

|| = Mozilla Documentation

&& = Mozilla Documentation


0

Soluzione destrutturante

Il contenuto della domanda potrebbe essere cambiato, quindi cercherò di rispondere accuratamente.

La destrutturazione ti consente di estrarre valori da qualsiasi cosa con proprietà. È inoltre possibile definire valori predefiniti quando null / undefined e alias del nome.

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

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

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

NOTA: le maiuscole sono importanti

Se lavori con un array, ecco come lo fai.

In questo caso, il nome viene estratto da ogni oggetto nell'array e gli viene assegnato il proprio alias. Poiché l'oggetto potrebbe non esistere è = {}stato aggiunto anche.

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

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

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

Tutorial più dettagliato

Supporto browser 92% luglio 2020

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.