【问题标题】:Is there something like the swift optional chaining in javascript?javascript中是否有类似快速可选链接的东西?
【发布时间】:2021-10-01 08:08:11
【问题描述】:

我在 javascript 中做了很多类似这样的代码

if (params && params.profile && params.profile.address && params.profile.address.default)

我必须检查每个可选的,它变得非常乏味。 javascript中是否有更好的方法,类似于swift处理选项的方式,例如

if let checked = params?.profile?.address?.default?

【问题讨论】:

标签: javascript swift optional


【解决方案1】:

Optional chaining has now been added to the language 使用与 Swift 相同的 ?. 语法,因此我建议您这样做,除非您需要支持较旧的浏览器版本。

如果你这样做了,我已经写了一个函数来处理这个:

function getSafe (func) {
    try {
        return func()
    } catch (e) {
        if (e instanceof TypeError) {
            return undefined
        } else {
            throw e
        }
    }
}

这样称呼它:

if (getSafe(() => params.profile.address.default))

这是可行的,因为通过将其包装在匿名函数中,直到 try/catch 块才会对其进行评估,然后如果任何父属性未定义,该块将捕获错误并返回 undefined

检查e 是否为TypeError 可以防止它吞下函数可能抛出的任何其他错误,因此仍然可以根据需要处理这些错误。如果您希望它在出现任何错误时返回 undefined,您可以删除该部分:

function getSafeNoErrors (func) {
    try {
        return func()
    } catch {
        return undefined
    }
}

【讨论】:

    【解决方案2】:

    原生JS中没有这样的运算符。

    但是,有一个 Babel 插件可以实现这一点,请查看https://github.com/davidyaha/ecmascript-optionals-proposal

    另外,请参考Null-safe property access (and conditional assignment) in ES6/2015了解更多参考资料

    【讨论】:

      【解决方案3】:

      2020 回答,它存在!!!

      您现在可以直接使用?.(可选链接)内联来安全地测试是否存在。所有现代浏览器都支持它。

      如果属性存在,?. 会进行下一次检查,或者返回有效值。任何故障都会立即短路并返回undefined

      const example = {a: ["first", {b:3}, false]}
      
      example?.a  // ["first", {b:3}, false]
      example?.b  // undefined
      
      // Dynamic properties ?.[]
      example?.a?.[0]     // "first"
      example?.a?.[1]?.a  // undefined
      example?.a?.[1]?.b  // 3
      
      // Functions ?.()
      null?.()                // undefined
      validFunction?.()       // result
      (() => {return 1})?.()  // 1
      
      // DOM Access
      domElement?.parentElement?.children?.[3]?.nextElementSibling
      

      如果不检查大小写,则左侧属性必须存在。如果没有,它会抛出异常。

      example?.First         // undefined
      example?.First.Second  // Uncaught TypeError: Cannot read property 'Second' of undefined
      

      ?. Browser Support - 82%,2020 年 10 月

      Node Support - 14+

      Mozilla Documentation

      【讨论】:

        【解决方案4】:
        function optionalChaining(obj, chain) {
          return chain
            .split('.')
            .reduce(function(acc, val) {
                return acc ? acc[val] : undefined;
            }, obj);
        }
        
        var user = {
         address: {
          street: 'No.969 West WenYi Road',
        },
         a: { b: { c: 2 } },
        }
        
        optionalChaining(user, 'address.street'); // 'No.969 West WenYi Road'
        optionalChaining(user, 'a.b.c') // 2
        

        该函数可以模拟可选链。

        【讨论】:

          【解决方案5】:

          是的,有一个。 在 ES2020 中,他们添加了可选链接和可选函数调用。

             const person = {
                  name: "Someone",
                  age: 28
              }
              console.log(person?.name) // "Someone"
              console.log(person?.["age"]) // 28
              person?.getAge?.() //   no errors, just undefined
          

          【讨论】:

            【解决方案6】:

            只是添加到上面的答案,你现在可以直接从 NPM 安装这个 babel 插件:

            https://www.npmjs.com/package/babel-plugin-transform-optional-chaining

            obj?.prop       // optional static property access
            obj?.[expr]     // optional dynamic property access
            func?.(...args) // optional function or method call
            

            注意事项:

            为了让 foo?.3:0 被解析为 foo ? .3 : 0(根据向后兼容的要求),在词汇语法级别添加了一个简单的前瞻,以便字符序列 ?。在这种情况下不会被解释为单个标记(?. 标记不能紧跟十进制数字)。

            https://github.com/tc39/proposal-optional-chaining

            也值得一试:

            https://github.com/tc39/proposal-nullish-coalescing

            https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-nullish-coalescing-operator

            【讨论】:

              猜你喜欢
              • 2011-01-21
              • 1970-01-01
              • 1970-01-01
              • 2018-04-13
              • 1970-01-01
              • 2021-09-29
              • 2016-10-17
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多