JavaScript中Object.entries对CSSKeywordValue类实例无效且对象对比失败
问题原因与解决方案
核心原因:CSSKeywordValue是特殊的CSSOM封装对象
你拿到的Object1和Object2是CSSKeywordValue实例,属于浏览器CSSOM API的原生对象,这类对象的属性并非定义在自身实例上,而是通过**原型链上的访问器(Getter)**提供的:
Object.getOwnPropertyNames、Object.entries等方法仅遍历对象自身的属性,所以返回空数组- 展开运算符
{...obj}也只会复制自身可枚举属性,因此得到空对象 ===、Object.is以及lodash/underscore的isEqual默认对比逻辑无法识别这类对象的实际值:===和Object.is比较的是对象引用,两个不同实例引用必然不同,返回false- lodash的
isEqual默认不遍历原型链属性,只会对比自身属性,因此也判断为不相等
正确的处理方式
1. 直接访问value属性对比实际值
CSSKeywordValue实例提供了value属性,直接获取这个字符串值进行对比即可:
console.log('实际值对比', Object1.value === Object2.value); // 输出:实际值对比 false(因为一个是'flex',一个是'block')
如果是两个相同值的CSSKeywordValue实例,这个对比会返回true。
2. 通用处理:使用toString()方法
所有CSSStyleValue子类(包括CSSKeywordValue、CSSNumericValue等)都实现了toString()方法,会返回对应的CSS字符串值:
console.log('toString对比', Object1.toString() === Object2.toString());
3. 自定义通用对比函数
如果需要处理多种CSSOM值类型,可以写一个简单的对比函数:
function isCSSValueEqual(a, b) { // 先判断引用是否相同 if (a === b) return true; // 判断是否为CSSStyleValue实例 if (a instanceof CSSStyleValue && b instanceof CSSStyleValue) { // 对比字符串化后的值 return a.toString() === b.toString(); } // 其他类型用常规对比 return Object.is(a, b); } console.log('自定义对比', isCSSValueEqual(Object1, Object2));
补充验证:查看原型链属性
如果想确认原型上的属性,可以用Object.getOwnPropertyDescriptors查看原型对象:
console.log('CSSKeywordValue原型属性', Object.getOwnPropertyDescriptors(Object1.__proto__));
你会看到value是一个带有Getter的访问器属性,这就是为什么直接遍历实例拿不到它的原因。
内容的提问来源于stack exchange,提问作者Faizan Anwer Ali
相关产品推荐
相关产品推荐

