Замініть значення, якщо в JavaScript не встановлено значення чи не визначено


128

У мене є вимога застосувати ??оператор C # до JavaScript, і я не знаю як. Розглянемо це в C #:

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

Тепер у мене це налаштування в 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

Як це зробити правильно?

Дякую.

EDIT: Я помітив половину проблеми: я не можу використовувати позначення "індексатор" для об'єктів ( my_object[0]). Чи є спосіб її обійти? (Я не знаю назви властивостей фільтрів заздалегідь і не хочу повторювати їх).

Відповіді:


271

Ось еквівалент JavaScript:

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

Зауважте, що логічний оператор|| не повертає булевого значення, а перше значення, яке може бути перетворене в true .

Додатково використовуйте масив об'єктів замість одного об'єкта:

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

Це можна отримати за допомогою індексу.


57
Зауважте, що це не працює, якщо 0 - дійсне значення i.
jt000

13
Якщо що - небудь falsey потенційно дійсний вхід ( 0, false, порожній рядок), я хотів би зробити що - щось на зразок цього , замість: var j = (i === null) ? 10 : i;Який буде тільки замінити null, а не що - небудь , що може бути визнано неправильним.
DBS

Чи є еквівалент для цього в Groovy?
користувач6123723

якщо iне визначено, це призведе до помилки. мені видається марним .. (?)
phil294

@ phil294 var j = (i != null ? i : 10);має працювати, тому що undefinedце ==null, так i != nullі falseдля nullі undefined.
ToolmakerSteve

6

Я помітив половину проблеми: я не можу використовувати позначення 'індексатор' для об’єктів (my_object [0]). Чи є спосіб її обійти?

Немає; літеральний об'єкт, як випливає з назви, є об'єктом , а не масивом, тому ви не можете просто отримати властивість на основі індексу, оскільки немає конкретного порядку їх властивостей. Єдиний спосіб отримати їх значення - це використовувати конкретну назву:

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

Або повторюючи їх за допомогою for ... inциклу:

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

1
@LinusGeffarth Зауважте, що цей кумедний for inцикл JS працює лише на об'єктних літералах! Він невдало спрацьовує на масивах JS (дає індекс) та JS Maps (дає undefined). Сподіваємось, ви цього не забудете, щоб не стати сюрпризом налагодження! хР
Варуна

4

Відповідь ES2020

Новий Nullish Coalescing Operator, нарешті, доступний на JavaScript, хоча підтримка браузера обмежена. За даними канюзи лише 48,34% браузерів (станом на квітень 2020 року).

Згідно з документацією,

Нульовий оператор злиття (??) - це логічний оператор, який повертає правий бік операнда, коли його лівий операнд є нульовим або невизначеним, а в іншому випадку повертає його лівий операнд.

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

Це гарантує , що обидва ваших змінні матиме резервне значення , ''якщо filters[0]або filters[1]є null, абоundefined .

Візьміть до уваги, що оператор зведення нуля не повертає значення за замовчуванням для інших типів хибного значення, таких як 0і ''. Якщо ви хочете врахувати всі помилкові значення, вам слід скористатися оператором АБО ||.


0

Логічне нульове призначення, рішення 2020+

Новий оператор в даний час додається в браузерах, ??=. Це еквівалентно value = value ?? defaultValue.

||=а &&=також приходять, посилання нижче.

Це перевіряє, чи ліва сторона не визначена або нульова, коротке замикання якщо вже визначено. Якщо ні, лівій стороні присвоюється значення правого боку.

Основні приклади

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

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

// Equivalent to
a = a ?? true

Приклади об'єктів / масивів

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

Приклад функціоналу

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 }

?? = Підтримка браузера липень 2020 р. - .03%

?? = Документація Mozilla

|| = Документація Mozilla

&& = Документація Mozilla


0

Розчин деструктуризації

Вміст питання, можливо, змінився, тому я спробую відповісти ретельно.

Деструкція дозволяє витягувати значення з усього, що має властивості. Ви також можете визначити значення за замовчуванням, коли null / undefined та псевдоніми імен.

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

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

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

ПРИМІТКА. Капіталізація має значення

Якщо ви працюєте з масивом, ось як це зробити.

У цьому випадку ім'я вилучається з кожного об'єкта в масиві і надається його власний псевдонім. Оскільки об'єкт може не існувати, = {}також було додано.

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

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

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

Більш докладний підручник

Підтримка браузера 92% липня 2020 року

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.