【问题标题】:What does the ?. syntax mean in JavaScript?是什么? JavaScript 中的语法是什么意思?
【发布时间】:2020-06-01 12:11:41
【问题描述】:

我在一个 React 项目中遇到了类似 C# 的代码。我无法确认此语法是否正确。我没有找到任何支持这种语法的最新 ES 版本。在当前情况下,我无权执行和检查此代码。

我尝试在浏览控制台中测试此语法并遇到错误:

{cart?.widgets?.items.map(widget => (
        <div className="billing-details__box" key={widget.id}>
          <p className="m-0">{widget.name}</p>
          <p className="my-0">{widget.value} $</p>
        </div>
 ))}

我对上述代码的担忧是cart?.widgets?.items 是否会引发任何错误。

【问题讨论】:

标签: javascript


【解决方案1】:

我无法确认此语法是否正确。

它是正确的 TypeScript 代码,并且是正确的 JavaScript,具体取决于您运行它的引擎。Chrome (V8) 已经支持这种语法(请参阅 caniuse.com)。

您可以在此处阅读更多关于 proposal to add this syntax 未来 JS 规范的信息。

这是什么?

这种语法称为可选链接运算符,它允许您访问对象上可能存在或不存在的属性而无需检查属性是否存在,无论多深属性访问表达式是

例如,假设我们有这样的对象:

const user = {
  details: {
    name: "SpongeBob SquarePants"
  },
  repo: null
};

我们想得到他们的名字,如果存在的话,还有一些属性user.repo.url。我们可以使用可选的链接运算符来获取两者,而不必担心repo 是否是一个对象:

console.log(user.details.name) //=> "SpongeBob SquarePants"
console.log(user.repo.url) //=> undefined

它也适用于函数调用。例如,假设user.repo 有一个值,我们知道它将是一个返回字符串的函数。但是,有时,如上所述,它可能不是一个函数。如果函数存在,我们可以执行以下操作来调用该函数,但如果user.repo.url 处的值不是函数,则代码不会抛出错误:

console.log(user.repo?.url()) //=> undefined

没有可选的链接运算符?

您可以通过显式检查您正在访问的属性链中每个对象属性的真实性来实现与可选链接运算符类似的行为。

这可以通过利用 JavaScript 的 short-circuit evaluation 行为来完成,或者更明显的是使用 ternary operator

看起来像这样:

function getItems_shortCircuit(obj) {
  return obj && obj.widgets && obj.widgets.items
}

function getItems_ternary(obj) {
  return obj 
    ? obj.widgets 
      ? obj.widgets.items 
        ? obj.widgets.items 
        : null 
      : null
    : null
}

let cart = {
  widgets: null
}

console.log(getItems_shortCircuit(cart)) //=> null

cart.widgets = {
  items: ["a", "b"]
}

console.log(getItems_ternary(cart)) //=> ["a", "b"]

我对上述代码的担忧是cart?.widgets?.items 是否会引发任何错误。

这取决于项目是否使用 TypeScript,它支持开箱即用的optional chaining (?.)。你可以在TypeScript documentation阅读它。

如果你不使用 TypeScript,那么你必须使用一些 ESNext 编译器来编译你的应用程序,比如 Babel,它有 @babel/plugin-proposal-optional-chaining plugin

【讨论】:

  • 你有点错了,可选链实际上已经是正确的 JavaScript 并且在 Chrome 80+(目前是默认版本)和 Firefox 74+(目前是开发版本)中有效现在。但是,如果您针对其他浏览器,您仍然需要进行转译。 caniuse.com/#search=optional%20chaining
  • 是的,我很高兴看到它在本月初在 Chrome 中上线。很好的答案!
  • 我猜对于其他浏览器,babel 会将此代码转换为支持的 javascript 代码
  • @VirajSingh 这是正确的——只要你使用答案中链接的插件,一旦它被 Babel 编译,你就可以在任何地方使用这个语法。
  • 如果您不知道,nullish coalescing operator ?? 现在也在 Chome 80+ 和常规 Firefox (72+) 中使用!现在我们只需要 Safari 和 Edge 即可使用该程序!
【解决方案2】:

可选链是JS的新特性。

基本上是一样的:

{cart && cart.widgets && cart.widgets.items.map(widget => (
        <div className="billing-details__box" key={widget.id}>
          <p className="m-0">{widget.name}</p>
          <p className="my-0">{widget.value} $</p>
        </div>
 ))}

欲了解更多详情,请务必访问V8 guide

【讨论】:

    【解决方案3】:

    它将由 Babel 编译并且可以工作。 https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining

    【讨论】:

      【解决方案4】:

      这可能是来自 Typescript 的 optional chaining

      【讨论】:

      【解决方案5】:

      它是可选链接,如果您使用 polyfill,它不会导致任何错误。 “?。” - 默认还不支持

      【讨论】:

      猜你喜欢
      • 2013-11-02
      • 2017-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-15
      • 2018-07-17
      • 1970-01-01
      • 2011-01-19
      相关资源
      最近更新 更多