ES5与ES6对象遍历对比异常:字谜求解代码差异原因排查
为什么ES5遍历对象的字谜求解代码无法正常工作?
你提到用ES6方式遍历对比字符映射表时没问题,但换成ES5的for...in写法就失效,核心问题出在**for...in遍历的范围和ES6遍历方式的差异**上,我给你拆解清楚:
核心差异:遍历的属性范围不同
ES6里你可能用的是类似for (const char of Object.keys(aCharMap))这种方式,Object.keys()只会返回对象自身的可枚举属性;但ES5的for...in循环会遍历对象自身+原型链上所有可枚举属性。
举个极端点的例子:如果之前有代码不小心给Object.prototype加了自定义属性(比如Object.prototype.test = 'xxx'),那for...in遍历aCharMap时,会把test也当成一个字符键来对比,自然就会返回错误的结果,而ES6的遍历方式完全不会碰原型链上的属性。
你的ES5代码遗漏了什么?
你原来的ES5写法大概率没加hasOwnProperty()判断,导致把原型链上的属性也纳入了对比。比如错误的写法是:
for (let char in aCharMap) { if (aCharMap[char] !== bCharMap[char]) { return false; } }
而正确的ES5写法需要加上hasOwnProperty()来过滤原型链属性:
for (let char in aCharMap) { // 只处理对象自身的属性 if (aCharMap.hasOwnProperty(char)) { if (aCharMap[char] !== bCharMap[char]) { return false; } } }
或者换一种更稳妥的ES5写法,用Object.keys()来遍历(本质和ES6的遍历逻辑一致):
var keys = Object.keys(aCharMap); for (var i = 0; i < keys.length; i++) { var char = keys[i]; if (aCharMap[char] !== bCharMap[char]) { return false; } }
验证一下
假设你的buildCharMap函数是正常生成字符计数的(比如把字符串转成键为字符、值为出现次数的对象),那加上hasOwnProperty判断后,ES5版本就能和ES6版本表现一致了——因为现在只会对比两个字符映射表自身的字符键,不会被原型链上的额外属性干扰。
内容的提问来源于stack exchange,提问作者Alexander Leismann
相关产品推荐
相关产品推荐

