为何Object.hasOwn检查p.style.display在Firefox中返回false?
问题描述
尝试使用Object.hasOwn(pitem.style, 'display')检查段落元素的style对象是否包含display属性时,发现浏览器差异:Chrome中返回true,Firefox 116.0.1 64位版本中返回false。但直接设置pitem.style.display的值可以正常生效。
可复现代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript"> function paragraphDisplayStyle() { let pitem = document.getElementById('pitem'); console.log(Object.getPrototypeOf(pitem.style)); // CSS2PropertiesPrototype console.log(pitem.style.display); // empty string console.log(Object.hasOwn(pitem.style, 'display')); // false. but why? pitem.style.display = 'none'; // setting the display value works fine } </script> </head> <body> <p id="pitem" onclick="paragraphDisplayStyle()">Content</p> </body> </html>
原因分析
这不是Firefox的实现问题,而是不同浏览器对CSSStyleDeclaration(即HTMLElement.style对应的对象)的属性存储策略不同:
- Chrome会预先将所有CSS属性作为自身属性挂载到
style对象上,即使没有设置过值,这些属性也存在,所以Object.hasOwn返回true,此时读取属性得到空字符串是因为属性值未初始化。 - Firefox则是通过原型链上的getter/setter来处理未设置过的CSS属性,这些属性并不存在于
style对象自身,只有当你显式设置过属性值后,该属性才会被添加为style的自身属性,所以未设置时Object.hasOwn返回false。
直接设置pitem.style.display能生效,是因为无论哪种实现,原型链上都存在对应的setter方法,会处理赋值操作并将属性同步到元素的行内样式中。
正确的检查方式
如果想判断display属性是否被设置过(即行内样式中存在该属性),正确的做法是检查属性值是否为空字符串:
// 检查是否设置过display行内样式 if (pitem.style.display !== '') { // 已设置 }
或者使用CSSStyleDeclaration的标准方法getPropertyValue:
if (pitem.style.getPropertyValue('display') !== '') { // 已设置 }
内容的提问来源于stack exchange,提问作者lonious
相关产品推荐
相关产品推荐

