使用无效合并运算符 (??) 检查对象中是否存在键的注意事项?
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';
但是,在这种情况下,它的替代方案(主要是 in
和 hasOwnProperty
)有其警告和风险。如 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';
使用 nullish 合并运算符 (??
),人们很想使用它来为不存在的对象键指定默认值,如答案 here 中所建议的,例如:
let a = foo.bar ?? 'default';
但是,在这种情况下,它的替代方案(主要是 in
和 hasOwnProperty
)有其警告和风险。如 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';