【问题标题】:Set a variable if undefined in JavaScript如果在 JavaScript 中未定义,则设置变量
【发布时间】:2011-03-23 18:06:57
【问题描述】:

我知道我可以测试一个 JavaScript 变量,然后定义它是否是 undefined,但是有没有什么说法

var setVariable = localStorage.getItem('value') || 0;

似乎是一种更清晰的方式,我很确定我在其他语言中看到过。

【问题讨论】:

  • 不是对“未定义”的测试,而是对“假”的测试
  • 请注意,如果用户禁用了 cookie(至少在 Chrome 中),localStorage.getItem() 将抛出异常,因此您可能希望将其包装在 try...catch 子句中

标签: javascript undefined


【解决方案1】:

逻辑空赋值,ES2020+ 解决方案

新的运算符目前正在添加到浏览器中,??=||=&&=。本帖将重点关注??=

这会检查左侧是否为undefinednull,如果已定义则短路。如果不是,则将右侧分配给左侧变量。

比较方法

// Using ??=
name ??= "Dave"

// Previously, ES2020
name = name ?? "Dave"

// or
if (typeof name === "undefined" || name === null) {
    name = true
}

// Before that (not equivalent, but commonly used)
name = name || "Dave" // Now: name ||= "Dave"

基本示例

let a       // undefined
let b = null
let c = false

a ??= true  // true
b ??= true  // true
c ??= true  // false

对象/数组示例

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" }

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

??= Mozilla Documentation

||= Mozilla Documentation

&&= Mozilla Documentation

【讨论】:

  • 将这个答案复制到另外两个问题(Replace a value if null or undefined in JavaScriptIs there a “null coalescing” operator in JavaScript?)真的是个好主意吗?将 VTC 作为副本或链接到 cmets 中的相关问题不是更好吗?
  • 问题都略有不同;答案也是如此。这些示例一目了然地改进了内联上下文。可能可以链接以获得更多详细信息,但需要额外的跳跃,这可能会导致人们跳过解决方案
  • 请注意,某些 IDE (NetBeans) 将 ??= 检测为无效语法。默认自动源格式会将其转换为?? =,中间有一个空格,这是无效的 JS。现在要弄清楚如何自定义自动格式化程序...
  • 不敢相信这还不被支持,这么基本的功能
  • 遗憾的是,这似乎不适用于router["GET"]?.["/admin"] ??= {"/admin": handler}; 等嵌套属性。也许更深层次的抽象会更好。
【解决方案2】:

是的,它可以这样做,但严格来说,如果检索到的值是 falsey,它将分配默认值,而不是真正的 undefined。因此,它不仅匹配undefined,而且匹配nullfalse0NaN""(但"0")。

如果您只想在变量严格为undefined 时设置为默认值,那么最安全的方法是编写:

var x = (typeof x === 'undefined') ? your_default_value : x;

在较新的浏览器上,编写实际上是安全的:

var x = (x === undefined) ? your_default_value : x;

但请注意,在旧版浏览器上可能会破坏这一点,在旧版浏览器中允许声明具有已定义值的名为 undefined 的变量,从而导致测试失败。

【讨论】:

  • 我很惊讶这种模式没有包含在更多的 JS 库中。
  • var x = (x === undefined ? def_val : x); 用作稍长的var x = (typeof x === 'undefined') ? def_val : x; 是否有缺点。行为是否不同?
  • @marco 在旧版浏览器中,undefined 可能被重新定义,导致相等性测试失败。
  • @Alnitak 使用与 OP 使用的语法类似的语法并仍检查未定义的最佳方法是什么?
  • @IvoPereira 您不能在严格测试未定义的情况下使用|| 方法,您必须使用带有条件的undefined 的显式测试。
【解决方案3】:

ES2020 答案

使用Nullish Coalescing 运算符,如果value 为空或未定义,您可以设置默认值。

const setVariable = localStorage.getItem('value') ?? 0;

但是,您应该注意,nullish 合并运算符不会返回其他类型的假值(例如 0'')的默认值。

但是,请注意browser support。您可能需要使用像 Babel 这样的 JavaScript 编译器将其转换为更向后兼容的东西。如果你使用的是 Node.js,已经支持since version 14

【讨论】:

    【解决方案4】:

    您可以使用以下任何一种方式。

    let x;
    let y = 4;
    x || (x = y)
    

    在 ES12 或之后

    let x;
    let y = 4;
    x ||= y;
    

    【讨论】:

    • 这里有already been suggested||= 如果变量只是未定义,则不会设置它;如果它是虚假的,它会设置它。
    【解决方案5】:

    2018 ES6 的答案是

    return Object.is(x, undefined) ? y : x;
    

    如果变量x未定义,则返回变量y...否则如果变量x已定义,则返回变量x。

    【讨论】:

    • 据我所知,Object.is 在这种情况下并不比=== 好。 “=== 运算符(以及 == 运算符)将数值 -0 和 +0 视为相等,并将 Number.NaN 视为不等于 NaN。” (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) 没关系。
    • 我不同意。了解它们并使用适当的。特别是,如果两个操作数都可能是NaN,请使用Object.is
    • 如果 Object.is() 适用于 100% 的用例,而 === 适用于 98% 的用例,您为什么还要冒险使用 ===?例如:console.log(+0 === -0); // 输出 true,而 console.log(Object.is(+0, -0)); // 输出 false -- 哪个更好?负0和正0一样吗?这是你必须问自己的问题,但如果你使用 Object.is(),你总是知道答案。它们不相同,因此 false 的输出是正确且预期的结果。
    • 这里的特定上下文总是与undefined 进行比较。所以=== 将在 100% 的时间内工作,而不仅仅是 98%。 === 的优点是更容易阅读,尤其是一目了然,更短,并且避免了不必要的方法调用。就个人而言,我只会在情况需要时使用Object.is(),而在所有其他情况下更喜欢===
    • 绝对的;如果您是经验丰富的编码员。除非您不小心忘记了等号,否则在这种情况下调试 == 在某处不起作用的原因是我绝不希望任何开发人员这样做的。比抱歉更安全,总是使用 Object.is(),之所以包含在规范中,是为了帮助开发人员编写更少的错误代码。
    【解决方案6】:

    在我们的时代,你实际上可以用 JS 来做你的方法:

    // Your variable is null
    // or '', 0, false, undefined
    let x = null;
    
    // Set default value
    x = x || 'default value';
    
    console.log(x); // default value
    

    所以你的例子会起作用:

    const setVariable = localStorage.getItem('value') || 0;
    

    【讨论】:

      【解决方案7】:

      我需要在几个地方“设置一个未定义的变量”。我使用@Alnitak 答案创建了一个函数。希望它可以帮助某人。

      function setDefaultVal(value, defaultValue){
         return (value === undefined) ? defaultValue : value;
      }  
      

      用法:

      hasPoints = setDefaultVal(this.hasPoints, true);
      

      【讨论】:

        【解决方案8】:

        今天也遇到了这种情况,我不希望零被多个值覆盖。我们有一个文件,其中包含一些用于此类场景的常用实用程序方法。这是我为处理场景和灵活添加的内容。

        function getIfNotSet(value, newValue, overwriteNull, overwriteZero) {
            if (typeof (value) === 'undefined') {
                return newValue;
            } else if (value === null && overwriteNull === true) {
                return newValue;
            } else if (value === 0 && overwriteZero === true) {
                return newValue;
            } else {
                return value;
            }
        }
        

        如果我只想为未定义的值设置或还覆盖 null 或 0 值,则可以在最后两个参数是可选的情况下调用它。这是一个调用它的示例,如果 ID 未定义或为 null,则将 ID 设置为 -1,但不会覆盖 0 值。

        data.ID = Util.getIfNotSet(data.ID, -1, true);
        

        【讨论】:

          【解决方案9】:

          如果你是 FP (functional programming) 的粉丝,Ramda 有一个简洁的辅助函数 defaultTo

          用法:

          const result = defaultTo(30)(value)

          在处理undefined布尔值时更有用:

          const result2 = defaultTo(false)(dashboard.someValue)

          【讨论】:

          • 这正是 const result = value || 30;,除了使用中间函数和 +1000 字节库
          • @Adelin 不正确,它还处理布尔类型的错误。如果你已经在使用这个库(就像我一样),那么它非常有用,而且很简洁
          【解决方案10】:

          检查typeof而不是undefined似乎更合乎逻辑?我假设您在未定义时将 var 设置为 0 时期望一个数字:

          var getVariable = localStorage.getItem('value');
          var setVariable = (typeof getVariable == 'number') ? getVariable : 0;
          

          在这种情况下,如果 getVariable 不是数字(字符串、对象等),则 setVariable 设置为 0

          【讨论】:

            【解决方案11】:

            var setVariable = (typeof localStorage.getItem('value') !== 'undefined' && localStorage.getItem('value')) || 0;

            【讨论】:

            • 如果localStorage.getItem('value'))返回false,则不会也赋值为0
            【解决方案12】:

            即使默认值是布尔值也有效:

            var setVariable = ( (b = 0) => b )( localStorage.getItem('value') );
            

            【讨论】:

              【解决方案13】:

              在我看来,对于当前的 javascript 实现,

              var [result='default']=[possiblyUndefinedValue]
              

              是一种很好的方法(使用对象解构)。

              【讨论】:

                猜你喜欢
                • 2023-01-13
                • 1970-01-01
                • 1970-01-01
                • 2013-08-27
                • 1970-01-01
                • 1970-01-01
                • 2018-04-29
                • 2016-11-04
                • 1970-01-01
                相关资源
                最近更新 更多