Заменить значение, если ноль или не определено в JavaScript

У меня есть требование применить ?? 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]). Есть ли способ обойти это? (Я заранее не знаю имен свойств фильтров и не хочу их перебирать).

6 ответов

Решение

Вот эквивалент 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 ''

Это может быть доступно по индексу.

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] ?? '';

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

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

Логическое нулевое назначение, решение 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 г. - 3,7%

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

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

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

?? следует предпочесть ||потому что он проверяет только значения NULL и undefined.

Все приведенные ниже выражения верны:

      (null || 'x') === 'x' ;
(undefined || 'x') === 'x' ;
//Most of the times you don't want the result below
('' || 'x') === 'x'  ;
(0 || 'x') === 'x' ;
(false || 'x') === 'x' ;
//-----

//Using ?? is preferred
(null ?? 'x') === 'x' ;
(undefined ?? 'x') === 'x' ;
//?? works only for null and undefined, which is in general safer
('' ?? 'x') === '' ;
(0 ?? 'x') === 0 ;
(false ?? 'x') === false ;

Нижняя граница:

int j=i ?? 10;также отлично подходит для использования в javascript. Просто замените int с участием let.

Asterisk: проверьте совместимость браузера и, если вам действительно нужна поддержка этих других браузеров, используйте babel .

Я обнаружил половину проблемы: я не могу использовать нотацию "индексатор" для объектов (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
}

Разрушающее решение

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

Деструктуризация позволяет извлекать значения из всего, что имеет свойства. Вы также можете определить значения по умолчанию, когда 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 г.

Другие вопросы по тегам