跳到主要内容

idx:存在函数

·阅读时长2分钟
Timothy Yung
Facebook 工程经理

在 Facebook,我们经常需要访问通过 GraphQL 获取的数据结构中深度嵌套的值。在访问这些深度嵌套的值时,一个或多个中间字段为空是很常见的。这些中间字段为空的原因有很多,从隐私检查失败到仅仅是因为 null 恰好是表示非致命错误的最灵活方式。

不幸的是,访问这些深度嵌套的值目前既繁琐又冗长。

props.user &&
props.user.friends &&
props.user.friends[0] &&
props.user.friends[0].friends;

有一个 ECMAScript 提案引入了存在运算符,这将使操作更加方便。但在该提案最终确定之前,我们希望有一个能够改善我们生活质量、保持现有语言语义并鼓励使用 Flow 进行类型安全的解决方案。

我们想出了一个名为 idx 的存在性函数

idx(props, _ => _.user.friends[0].friends);

此代码片段中的调用与上面代码片段中的布尔表达式的行为类似,但重复性大大降低。idx 函数严格接受两个参数

  • 任何值,通常是您要访问嵌套值的对象或数组。
  • 一个函数,它接收第一个参数并访问其上的嵌套值。

理论上,idx 函数将尝试捕获访问 null 或 undefined 上的属性所导致的错误。如果捕获到此类错误,它将返回 null 或 undefined。(您可以在 idx.js 中查看其实现方式。)

在实践中,每次嵌套属性访问都进行 try-catch 是缓慢的,并且区分特定种类的 TypeError 是脆弱的。为了解决这些缺点,我们创建了一个 Babel 插件,将上面的 idx 调用转换为以下表达式

props.user == null
? props.user
: props.user.friends == null
? props.user.friends
: props.user.friends[0] == null
? props.user.friends[0]
: props.user.friends[0].friends;

最后,我们为 idx 添加了一个自定义的 Flow 类型声明,允许在第二个参数中进行遍历的类型检查,同时允许对可空属性进行嵌套访问。

该函数、Babel 插件和 Flow 声明现已 在 GitHub 上提供。通过安装 idxbabel-plugin-idx npm 包,并将“idx”添加到 .babelrc 文件中的插件列表中来使用它们。