这是我在《为什么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.b
和a?.b
都不旨在保留关于基本对象a
的任意信息,而仅用于给出关于该对象的属性"b"
的信息。如果属性"b"
在a
中不存在,则这由a.b === undefined
和a?.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")
产生123
,someLibraryFunction(undefined, "a")
产生undefined
,那么someLibraryFunction(null, "a")
产生什么"对于大多数被咨询的图书馆来说,答案似乎是undefined
。
这两者都不一定是我们使用undefined
而不是null
的确切原因。但他们指出,undefined
的力量似乎比null
的力量更有力量或耐力,并且undefined
最终占了上风,总是回到";a?.b
应该让您读取a
的属性b
而不必担心TypeError
";。