Заменить значение, если оно равно null или undefined в 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

Как мне это сделать правильно?

Спасибо.

РЕДАКТИРОВАТЬ: Я заметил половину проблемы: я не могу использовать нотацию «индексатор» для объектов ( my_object[0]). Есть ли способ обойти это? (Я не знаю заранее названия свойств фильтров и не хочу их перебирать).

Валентин Васильев
источник

Ответы:

271

Вот эквивалент JavaScript:

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

Обратите внимание, что логический оператор|| возвращает не логическое значение, а первое значение, которое можно преобразовать в истину .

Дополнительно используйте массив объектов вместо одного объекта:

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?
user6123723
если iне определено, это вызовет ошибку. мне кажется бесполезным таким образом .. (?)
phil294
@ phil294 var j = (i != null ? i : 10);должен работать, потому что он undefinedравен ==нулю, так 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). Надеюсь, вы не забудете это, иначе вас ждет сюрприз отладки! xP
varun 01
4

ES2020 Ответ

Новый Nullish Coalescing Operator наконец-то доступен на JavaScript, хотя поддержка браузером ограничена. По данным caniuse , поддерживается только 48,34% браузеров (по состоянию на апрель 2020 г.).

Согласно документации,

Оператор объединения с нулевым значением (??) - это логический оператор, который возвращает его правый операнд, когда его левый операнд имеет значение NULL или undefined, а в противном случае возвращает его левый операнд.

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

Это гарантирует, что обе ваши переменные будут иметь резервное значение ''if filters[0]или filters[1]are null, илиundefined .

Обратите внимание, что оператор объединения с нулевым значением не возвращает значение по умолчанию для других типов ложных значений, таких как 0и ''. Если вы хотите учесть все ложные значения, вам следует использовать оператор OR ||.

wentjun
источник
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 г. - 0,03%

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

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

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

Gibolt
источник
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 г.

Gibolt
источник