为什么 JavaScript 的可选链接使用 undefined 而不是保留 null?



这是我在《为什么TypeScript编译器用两个检查编译其可选的链接和null合并运算符》结尾偶然问到的一个后续问题?正如常驻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?.xtt==>t', undefined?.x);
console.log('null?.xttt==>t', null?.x);
console.log('null?.x === nullt==>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');
}

在可选链接方案的常见问题解答中,它说:

为什么(null)?.b的求值结果是undefined而不是null

a.ba?.b都不旨在保留关于基本对象a的任意信息,而仅用于给出关于该对象的属性"b"的信息。如果属性"b"a中不存在,则这由a.b === undefineda?.b === undefined反映。特别地,值null被认为没有属性;因此(null)?.b是未定义的。

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


当然,您并不是唯一一个期望a?.b应该传播a的零性的人。关于(null)?.b在(现已结束(问题tc39/提案可选链接#65和tc39/建议可选链接#69中应该是什么,存在着相当激烈的争论。

在tc39/poc#65中,我们看到进行了一次reddit民意调查,一致认为";总是CCD_ 23";超过";有时为CCD_ 24〃;。在tc39/poc#69中,有人对JS库进行了一项调查,这些库具有这种运算符的函数版本,如Undercore的property和Lodash的get,并问道:";如果someLibraryFunction({a: 123}, "a")产生123someLibraryFunction(undefined, "a")产生undefined,那么someLibraryFunction(null, "a")产生什么"对于大多数被咨询的图书馆来说,答案似乎是undefined

这两者都不一定是我们使用undefined而不是null的确切原因。但他们指出,undefined的力量似乎比null的力量更有力量或耐力,并且undefined最终占了上风,总是回到";a?.b应该让您读取a的属性b而不必担心TypeError";。

最新更新