Заменить значение, если ноль или не определено в 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%
??
следует предпочесть
||
потому что он проверяет только значения 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 г.