如果JavaScript中为null或未定义,则替换一个值


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])使用“索引器”表示法。有没有办法绕过它?(我事先不知道过滤器属性的名称,也不想对其进行迭代)。

Answers:


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'2

13
如果任何错误的输入可能是有效的输入(0,,false空字符串),我将改为执行以下操作:var j = (i === null) ? 10 : i;它将仅替换null,而不是任何可以评估为错误的输入。
DBS

在Groovy中有与此等效的功能吗?
user6123723 '18

如果i未定义,将引发错误。因此对我来说似乎没用..(?)
phil294

@ phil294 var j = (i != null ? i : 10);应该工作,因为undefined==零,所以i != nullfalse两个nullundefined
制造商史蒂夫(Steve)

6

我发现了问题的一半:我无法对对象(my_object [0])使用'indexer'表示法。有没有办法绕过它?

没有; 顾名思义,对象文字是一个对象,而不是数组,因此您不能简单地基于索引来检索属性,因为它们的属性没有特定的顺序。检索其值的唯一方法是使用特定名称:

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 inJS循环仅适用于对象文字!它在JS数组(给定索引)和JS Maps(给定undefined)上惨遭失败。希望您不要忘记这一点,以免您因调试而感到惊讶!xP
varun

4

ES2020答案

新的Nullish合并运算符终于可以在JavaScript上使用,尽管对浏览器的支持是有限的。根据caniuse的数据,截至2020年4月,仅支持48.34%的浏览器。

根据文档,

空合并运算符(??)是一个逻辑运算符,当其左侧操作数为null或未定义时返回其右侧操作数,否则返回其左侧操作数。

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

这样可以确保两个变量的后备值均为''if filters[0]filters[1]are nullundefined

请注意,空值合并运算符不会返回其他类型的伪造值(例如0和)的默认值''。如果要考虑所有虚假值,则应使用OR运算符||


0

逻辑无效分配,2020 +解决方案

当前正在将新的运算符添加到浏览器中??=。等同于value = value ?? defaultValue

||=并且&&=也即将到来,下面的链接。

这将检查左侧是否未定义或为null,如果已定义则短路。如果不是,则为左侧分配右侧值。

基本范例

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年7月-.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年7月

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.