【问题标题】:Replace a value if null or undefined in JavaScript如果 JavaScript 中为 null 或 undefined 则替换一个值
【发布时间】:2010-11-03 22:08:45
【问题描述】:

我需要将?? 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])。有没有办法绕过它? (我事先不知道过滤器属性的名称,也不想遍历它们)。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    这是等效的 JavaScript:

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

    注意logical operator || 不返回布尔值,而是返回第一个可以转换为true的值。

    另外使用一组对象而不是单个对象:

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

    可以通过索引访问。

    【讨论】:

    • 请注意,如果 0 是 i 的有效值,这将不起作用。
    • 如果任何错误的输入可能是有效的(0false、空字符串),我会这样做:var j = (i === null) ? 10 : i; 只会替换 null,而不是任何可以评估为假的东西。
    • Groovy 中是否有类似的功能?
    • 如果 i 未定义,这将引发错误。因此对我来说似乎没用..(?)
    • @phil294 var j = (i != null ? i : 10); 应该可以工作,因为undefined== null,所以i != null 对于nullundefined 都是false
    【解决方案2】:

    ES2020 答案

    新的Nullish Coalescing 运算符终于可以在 JavaScript 上使用了。但是,请注意browser support。您可能需要使用像 Babel 这样的 JavaScript 编译器将其转换为更向后兼容的东西。

    根据文档,

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

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

    如果filters[0]filters[1]nullundefined,这将确保您的两个变量都有一个备用值''

    请注意,nullish 合并运算符不会为其他类型的假值返回默认值,例如 0''。如果您想考虑所有虚假值,您应该使用 OR 运算符||

    【讨论】:

    • 你是指出这一点的精灵。完美,因为我们不支持 IE
    【解决方案3】:

    逻辑无效赋值,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 }
    

    ??= Browser Support 2021 年 9 月 - 90%

    ??= Mozilla Documentation

    ||= Mozilla Documentation

    &&= Mozilla Documentation

    【讨论】:

      【解决方案4】:

      我发现了一半的问题:我不能对对象 (my_object[0]) 使用“索引器”表示法。有没有办法绕过它?

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

      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
      }
      

      【讨论】:

      • @LinusGeffarth 请注意,这个有趣的for in JS 循环仅适用于对象字面量!它在 JS 数组(给出索引)和 JS 映射(给出undefined)上惨遭失败。希望您不要忘记这一点,以免您遇到调试惊喜! xP
      【解决方案5】:

      解构解决方案

      问题内容可能有所变化,所以我会尽量认真回答。

      解构允许您从任何具有属性的事物中提取值。您还可以在 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"
      

      More Detailed Tutorial

      Browser Support 92% 2020 年 7 月

      【讨论】:

        【解决方案6】:

        ?? 应该优先于 ||,因为它只检查空值和未定义

        以下所有表达式都为真:

        (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:勾选browser compatibility,如果您确实需要支持这些其他浏览器,请使用babel

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-11
          • 1970-01-01
          • 2018-11-02
          • 1970-01-01
          • 2021-01-01
          • 1970-01-01
          相关资源
          最近更新 更多