【问题标题】:Why does JavaScript's optional chaining use undefined instead of preserving null?为什么 JavaScript 的可选链使用 undefined 而不是保留 null?
【发布时间】:2021-11-05 16:06:17
【问题描述】:

这是我在 Why does the TypeScript compiler compile its optional chaining and null-coalescing operators with two checks? 末尾顺便问的一个后续问题,正如常驻 TypeScript 传奇人物 jcalz 在评论中指出的那样,它确实值得提出自己的问题。

// Why does the JavaScript treat
x?.y
// as
x === null || x === void 0 ? void 0 : x.y
// instead of
x === null || x === void 0 ? x : x.y
// ?

x == null 时,后者将保留null,而前者始终返回undefined

现代浏览器原生支持?.,因此我们可以测试这种行为。

const test = () => {
  console.log('undefined?.x\t\t==>\t', undefined?.x);
  console.log('null?.x\t\t\t==>\t', null?.x);
  console.log('null?.x === null\t==>\t', null?.x === null);
};

try {
  eval('null?.x');
  test();
} catch {
  console.error('Your browser does not support optional chaining syntax.');
  console.info('While optional chaining is supported by all modern browsers, this will not work in browsers that do not support the syntax.')
  console.warn('????');
  console.info('Shocking, I know.');
  console.info('Compatibility chart: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining#browser_compatibility');
}

【问题讨论】:

  • 正如我在另一个问题中所说,这就是 optional chaining 在 JS 中的工作方式; null?.xundefined 而不是 null。那么您是在问为什么 TS 决定实施降级以生成符合 JS 规范的代码? (答案:当 TS 不正确地降级时,它会让小猫伤心????)或者你是在问为什么 JS 决定对undefined 进行可选链接短路,而不是保留传入的无效性的特殊味道? (答案:还不确定)
  • 啊,回答:github.com/tc39/proposal-optional-chaining#faq null?.xundefined 因为 nullx 属性将是 undefined,而不是 null,如果你可以取消引用 null任何其他缺少 x 属性的东西。
  • 啊,有一个 process 用于向 JS 引入功能。一旦提案达到“阶段 3”,意味着它很可能在不久的将来出现在 JS 中,并且它的细节大多是稳定的。此时,TS 根据规范实现它。因此,虽然从某种意义上说,“TS 先有它”在技术上是正确的,即 TS 版本在正式成为 EcmaScript 规范的一部分之前就具有该功能,但他们不能随意选择它会做什么。
  • 所以,我很乐意回答,但这与 TypeScript 本身并没有多大关系;也许您应该将问题编辑为关于 JS 的问题?
  • 我把它更新为关于 JS

标签: javascript language-design


【解决方案1】:

FAQ for the optional chaining proposal 中,它说:

为什么(null)?.b 评估为undefined 而不是null

  a.ba?.b 都不是为了保留有关基础对象 a 的任意信息,而只是提供有关该对象的属性 "b" 的信息。如果a 中缺少属性"b",则a.b === undefineda?.b === undefined 会反映这一点。 特别是,值null 被认为没有属性;因此,(null)?.b 未定义。

所以这似乎是这个问题的预期面向公众的答案。该属性不存在,因此可选链接为您提供了读取不存在属性 (undefined) 的正常行为,而无需担心抛出 TypeError


当然,你不是唯一一个期望a?.b 应该传播a 的无效性的人。关于(null)?.b 应该在tc39/proposal-optional-chaining#65tc39/proposal-optional-chaining#69 的(现已关闭的)问题中的内容存在相当激烈的辩论。

在 tc39/poc#65 中,我们看到执行了reddit poll,并且共识支持“总是undefined”而不是“有时null”。在 tc39/poc#69 中,有人 did a survey 的 JS 库具有此类运算符的函数版本,例如 Undercore's propertyLodash's get,并问:“如果 someLibraryFunction({a: 123}, "a") 产生 123,而 someLibraryFunction(undefined, "a") 产生undefinedsomeLibraryFunction(null, "a") 生产什么?”对于大多数咨询过的图书馆来说,答案似乎是undefined

这些都不是我们使用undefined 而不是null 的明确原因。但他们表明undefined 的力量似乎比null 的力量具有更多的力量或耐力,并且undefined 最终占了上风,总是回到“a?.b 应该让你阅读a 的属性b 而不必担心TypeError”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    • 2020-11-19
    • 1970-01-01
    • 2023-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多