for...in遍历NodeList时propertyIsEnumerable检测keys返回false原因
问题原因说明
这个现象由两个核心逻辑共同导致:
- 你对
propertyIsEnumerable()方法的检测范围存在误解:这个方法只会判断调用该方法的对象自身持有的属性是否可枚举,不会顺着原型链向上查找属性。keys、entries、values这三个方法并不是你拿到的某个具体NodeList实例的自有属性,而是所有NodeList实例共享的、定义在NodeList.prototype原型对象上的方法,你在单个NodeList实例上调用propertyIsEnumerable("keys"),自然会返回false。如果要检测这几个方法本身的可枚举性,需要在原型对象上调用检测:NodeList.prototype.propertyIsEnumerable("keys")。 - for...in循环的遍历规则和你预期的不一致:for...in不会只遍历对象自身的属性,它会遍历对象自身+整条原型链上所有标记为
enumerable: true的属性。按照现行的Web规范,NodeList原型上的这几个迭代方法的可枚举标记本来应该是false,符合标准的现代浏览器中for...in根本不会遍历到这几个方法。你遇到的可遍历情况属于旧版浏览器的实现遗留问题:早期浏览器厂商首次给NodeList添加可迭代能力时,错误地把这几个方法的可枚举特性设为了true,这个bug在后续的浏览器迭代中已经被修复。
开发提示:不要使用for...in遍历数组、NodeList这类类数组结构。for...in本身是为遍历普通对象的可枚举属性设计的,遍历过程会覆盖原型链上的属性,很容易出现预期外的结果。遍历NodeList优先选择
for...of循环,也可以先通过Array.from()把NodeList转成真正的数组,再调用forEach、map等数组方法遍历。
内容的提问来源于stack exchange,提问作者Kat
相关产品推荐
相关产品推荐

