【问题标题】:How can I use optional chaining with arrays and functions?如何将可选链接与数组和函数一起使用?
【发布时间】:2022-04-27 02:53:29
【问题描述】:

我正在尝试将可选链接与数组而不是对象一起使用,但不知道如何做到这一点:

这就是我正在尝试做的myArray.filter(x => x.testKey === myTestKey)?[0]。 还尝试使用函数进行类似的操作:

let x = {a: () => {}, b: null}
console.log(x?b());

但它给出了类似的错误 - 我如何使用可选链接与数组或函数?

  • 你有什么输入数据,你想要什么结果?
  • 这是一个通用问题,不应该依赖于输入和输出 ? 进行空检查以防止长时间使用 && && 链。

标签: javascript arrays typescript function optional-chaining


【解决方案1】:

您需要在? 之后放置. 以使用可选链接:

myArray.filter(x => x.testKey === myTestKey)?.[0]

Playground link

仅使用? 会使编译器认为您正在尝试使用条件运算符(然后它会引发错误,因为它稍后看不到:

可选链接不仅仅是 TypeScript 的东西 - 它也是一个完成的提案 in plain JavaScript

它可以与上面的括号表示法一起使用,但也可以与点表示法属性访问一起使用:

const obj = {
  prop2: {
    nested2: 'val2'
  }
};

console.log(
  obj.prop1?.nested1,
  obj.prop2?.nested2
);

并使用函数调用:

const obj = {
  fn2: () => console.log('fn2 running')
};

obj.fn1?.();
obj.fn2?.();

【讨论】:

  • 这也适用于 Javascript(我认为是从 2020 年开始)。同样,如果函数不是nullundefined,也可以使用foo?.()
【解决方案2】:

official documentation 的新功能页面上进行了一些搜索后才找到它

使用数组的正确方法是在? 之后添加.

所以它会像

myArray.filter(x => x.testKey === myTestKey)?.[0]

我想进一步说明我的上述问题案例到底发生了什么。

myArray.filter(x => x.testKey === myTestKey)?[0]

转译为

const result = myArray.filter(x => x.testKey === myTestKey) ? [0] : ;

因此它会引发错误,因为 : 之后缺少某些内容,并且您可能不希望将代码转换为此。

感谢Certain Performance的回答,我学到了关于打字稿的新东西,尤其是工具https://www.typescriptlang.org/play/index.html

【讨论】:

    【解决方案3】:

    我在 Edge Chromium 84 上测试的 ECMA 262 (2020) 可以在没有 TypeScript 转译器的情况下执行 Optional Chaining 运算符:

    // All result are undefined
    const a = {};
    
    console.log(a?.b);
    console.log(a?.["b-foo-1"]);
    console.log(a?.b?.());
    
    // Note that the following statements throw exceptions:
    a?.(); // TypeError: a is not a function
    a?.b(); // TypeError: a?.b is not a function
    

    CanIUse: Chrome 80+, Firefox 74+

    【讨论】:

      【解决方案4】:

      函数不必在对象内部,您也可以使用可选链接运行函数,如下所示:

      someFunction?.();
      

      如果someFunction 存在,它将运行,否则将跳过执行并且不会出错。

      这种技术实际上非常有用,特别是如果您使用可重用组件并且某些组件可能没有此功能。

      【讨论】:

        【解决方案5】:

        official documentation的新页面搜索了一下,发现了。

        您需要在? 之后放置. 以使用可选链接。

        所以会是这样,

        myArray.filter(x => x.testKey === myTestKey)?.[0]
        

        仅使用? 使编译器认为您正在尝试使用条件运算符(然后它会导致错误,因为它稍后看不到:

        【讨论】:

          【解决方案6】:

          好吧,即使我们找到了正确的语法,代码对我来说也没有多大意义。

          上面代码中的可选链接确保myArray.filter(x => x.testKey === myTestKey) 的结果不是null 而不是undefined(您可以查看TS 输出)。但无论如何这是不可能的,因为filter 方法的结果始终是array。由于 JavaScript 不会抛出“超出数组边界”,因此当您尝试访问任何索引时始终是安全的 - 如果此元素不存在,您将获得 undefined

          更清楚的例子:

          const myArray: string[] = undefined
          console.log(myArray.filter(x => x)?.[0]) //throws Cannot read property 'filter' of undefined
          
          //in this example the optional chaining protects us from undefined array
          const myArray: string[] = undefined
          console.log(myArray?.filter(x => x)[0]) //outputs "undefined"
          

          【讨论】:

          • ? 那很有趣。这是一个普遍的问题。如果你想要 [0].key 你会得到错误无法读取未定义的属性键,对吗?我不得不提出这个问题是为了在不同的地方使用
          • 该问题具有通用标题,但所描述的问题非常具体。除此之外,您正在解释不需要的示例中的可选链接。我一点也不觉得这很有趣。
          • 如果您赞成投票,我觉得您接近它的方式很有趣我认为这符合您的目的有任何建议我很乐意接受这些更改
          猜你喜欢
          • 2020-04-24
          • 2014-11-15
          • 2019-08-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-01
          • 2015-05-03
          • 1970-01-01
          相关资源
          最近更新 更多