小于 1 分钟
在这段代码里:
function iterate(obj){
var res=[];
for(var key in obj){
if(obj.hasOwnProperty(key))
res.push(key+': '+obj[key]);
}
return res;
}
for...in 循环本身确实只会遍历对象自身的可枚举属性(不包括不可枚举属性),不会遍历原型链上的属性 —— 这是很多人误解的地方。
但这里的关键是:for...in 会遍历原型链上 可枚举 的属性。
✅ 举个例子你就明白了:
function Person() {}
Person.prototype.sayHi = function () {};
const p = new Person();
p.name = 'Tom';
for (let key in p) {
console.log(key); // 输出:name, sayHi
}
看到了吗?sayHi 是定义在原型链上的,但也被 for...in 遍历到了。
✅ 而加上 hasOwnProperty 后:
for (let key in p) {
if (p.hasOwnProperty(key)) {
console.log(key); // 只输出:name
}
}
✅ 总结:
for...in会遍历原型链上可枚举的属性;hasOwnProperty的作用是过滤掉原型链上的属性,只保留对象自身的;- 所以不使用
hasOwnProperty结果不一样,除非你确定原型链上没有可枚举属性。
✅ 补充建议(现代写法):
如果你只想遍历对象自身的属性,可以用:
Object.keys(obj).forEach(key => {
console.log(key + ': ' + obj[key]);
});
这就不需要 hasOwnProperty 了,因为 Object.keys 只返回对象自身的可枚举属性。