使用无效合并运算符 (??) 检查对象中是否存在键的注意事项?

Caveats of using the nullish coalescing operator (??) to check for the existence of a key in an object?

使用 nullish 合并运算符 (??),人们很想使用它来为不存在的对象键指定默认值,如答案 here 中所建议的,例如:

let a = foo.bar ?? 'default';

但是,在这种情况下,它的替代方案(主要是 inhasOwnProperty)有其警告和风险。如 here. Calling <object>.hasOwnProperty(<key>) won't work, for example, if the object's hasOwnProperty is shadowed, as discussed here 所述,调用 <key> in <object> 匹配对象原型链中的键。当然,?? 也有自己需要注意的陷阱。

与检查任何对象中是否存在键的其他方法相比,?? 的缺陷是什么?


换句话说,执行以下操作的风险是:

let a = foo.bar ?? 'default';

接近这个

let a = 'bar' in foo ? foo.bar : 'default';

或者这个

let a = foo.hasOwnProperty('bar') ? foo.bar : 'default';

或者这个

let a = Object.prototype.hasOwnProperty.call(foo, 'bar') ? foo.bar : 'default';

或者两者有什么不同?

当您知道预期的对象类型时,您所谈论的风险是无关紧要的,在您的特定情况下是 bar 属性。没有Object.prototype.bar.

在 属性 访问后使用 ?? 的“风险”与进行 属性 访问的风险完全相同。您的语句 let a = foo.bar ?? 'default'; 等同于

let a = foo.bar == null ? 'default' : foo.bar;

或(不访问 属性 两次)

let a = foo.bar;
if (a == null) a = 'default';