在JavaScript中是否有类似于Swift可选链的东西?

26

我一直在使用JavaScript编写类似以下的代码:

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

这里需要检查每个可选项,这样做很繁琐。在JavaScript中是否有一种更好的方式,类似于Swift处理可选项的方式,例如:

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


可能是 https://dev59.com/5HE85IYBdhLWcg3wwWMb 的重复问题。 - CodingIntrigue
1
它来了!它已经被移动到第三阶段(截至2019年7月下旬)https://twitter.com/drosenwasser/status/1154456633642119168 - Aurelio
6个回答

10

使用与 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块中才被执行,如果任何父级属性未定义,则会触发try/catch块并返回undefined

检查e是否为TypeError可以防止它吞噬函数可能抛出的任何其他错误,因此还可以按需处理这些错误。如果想在任何错误时都返回undefined,可以删除该部分:

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

6

4

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

?. 浏览器支持 - 82%,截至2020年10月

Node 支持 - 版本 14+

Mozilla 文档


1

是的,有一个。

在ES2020中,增加了可选链和可选函数调用。

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

1
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

这个函数可以模拟可选链。

0

仅补充上面的答案,现在您可以直接从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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接