在JS中利用for...in循环遍历对象【踩坑】

在JS中利用for...in循环遍历对象【踩坑】

Tony哥
2023-01-12 / 0 评论 / 377 阅读 / 正在检测是否收录...

for...in循环可以在js中遍历对象或者数组,比如当我们想要输出内容中的所有对象,就可以使用for...in循环

//使用方法 for(键 in 对象)

var obj={
name:'Zhang',
score:60,
result:'及格'
}

for(var ergodic in obj){
console.log(obj[ergodic]);
}

运行结果

lcsgtne2.png

如果我们想隐藏(删除)部分内容,可以使用delete进行操作

<!DOCTYPE HTML>
<html>
<head>
<meta charset=utf-8" />
<title>CSDN Wellfancy</title>
 
</head>
<body>
<div></div>
<script>
//使用方法 for(键 in 对象)
 
var obj={
name:'Zhang',
score:60,
result:'及格'
}
 
delete obj.score;//隐藏obj中score的值
 
for(var ergodic in obj){
console.log(obj[ergodic]);
}
 
</script>
</body>
</html>

运行结果:
lcsguv3n.png

for in 的踩坑

但实际上往往再引用了很多其它框架后,由于每个库写法的不确定性可能会用到一些影响对象特有属性的一些写法如:prototype、__proto__与constructor等,那么for in 去遍历时就出现了一些事情
举例:某个js类中声明了一个:window.xyz={};window.xyz.__proto__.abcd=1123;
那么您的所有对象中都会被新增了一个abcd,那么循环出来的结果将是

Zhang
60
及格
1123
  • 我们来看下影响对象属性的一些属性定义
    首先,我们需要牢记两点:①__proto__和constructor属性是对象所独有的;② prototype属性是函数所独有的。但是由于JS中函数也是一种对象,所以函数也拥有__proto__和constructor属性,这点是致使我们产生困惑的很大原因之一。
    举个例子:

    function Foo() {...};
    let f1 = new Foo();

    以上代码表示创建一个构造函数Foo(),并用new关键字实例化该构造函数得到一个实例化对象f1。这里稍微补充一下new操作符将函数作为构造器进行调用时的过程:函数被调用,然后新创建一个对象,并且成了函数的上下文(也就是此时函数内部的this是指向该新创建的对象,这意味着我们可以在构造器函数内部通过this参数初始化值),最后返回该新对象的引用
    虽然是简简单单的两行代码,然而它们背后的关系却是错综复杂的,如下图所示:
    lcshx8ye.png
    上图有些复杂,如果不理解可以略过...详细了解...

其实您知道"abcd"不是我们要的

解决方案如下:

<!DOCTYPE HTML>
<html>
<head>
<meta charset=utf-8" />
<title>CSDN Wellfancy</title>
 
</head>
<body>
<div></div>
<script>
//使用方法 for(键 in 对象)
window.xyz={};
window.xyz.__proto__.abcd=1123;
var obj={
name:'Zhang',
score:60,
result:'及格'
}
 
delete obj.score;//隐藏obj中score的值
 
for(var ergodic in obj){
  if (obj.hasOwnProperty(ergodic)) {
    console.log(obj[ergodic]);
  }
}
 
</script>
</body>
</html>
综上所属,建议我们采用for in遍历对象时都加入hasOwnProperty的判断,以免后续逻辑被未知框架声明所污染
1

评论 (0)

取消