关于for的加强循环(for in(of))

117 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

前段时间遇到关于for in和for of的问题,然后自己稍稍整理梳理了一遍,正好好兄弟也遇到了,就写成文章给大家分享一下自己浅薄的理解。

for in和for of都是关于for的加强循环。

注:for of循环的是键值对中的值,for in循环的是键值对中的键

- for of

首先 for of循环的对象必须是可迭代的,也就是内部必须使用了@iterator方法的,StringArrayTypedArrayMap 和 Set等。那么常见的显然for of可以循环数组和字符串。

let a = [1,2,3,4]
for(let i of a)
{
  console.log(i)    //i依次为1 2 3 4
}

let string = 'abc'
for(let j of string){
    console.log(j)  //j依次为 a b c
}

由于object内部是没有@iterator方法的的 所以在对对象使用for of 的时候会报错

let a = { name : 'mhj' ,age:18}
for(let i of a)
{
  console.log(i)
}

image-20220404135448473.png

那么怎么样能够循环对象呢。

解决办法:让其内部使用@iterator(利用Object.keys()方法) 顾名思义:就是拿到对象中的key也就是键值对的键名

let a = { name : 'mhj' ,age:18}
console.log(Object.keys(a))   //结果为[name,age]
for(let i of Object.keys(a))     //将其变成数组后即可循环
{
    console.log(i)   //此时i依次打印 name,age
}

注意:for of循环时候拿到的是键值对中的值, 1 2 3 4和a b,但是在Object.keys()进行处理之后将其键值名单拎出来变成数组。就可以进行for of 循环

- for in

以任意顺序迭代一个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性。 常见的值定义数据和后台拿到的数据都属于可枚举对象。 那么很显然,for in既可以循环数组,也可以循环对象,与for of不同的是,for in循环的值是键值对中的键值,而for of循环的是键值对中的值。

let b = { name : 'mhj' ,age:18}
  for(let i in b){
  console.log(i)    //输出  name age  输出对象中的键值名
}

let a= [1,2,3,4]
 for(let i in a){
  console.log(i)    //输出 0 1 2 3 也就是数组的下标
}

值得一提的是for in在循环数组时还会一起循环数组的原型的方法属性, 例如

Array.prototype.contains = function() { return null } 
Array.prototype.subTitle= 'Flutter'
let a = [1,2,3,4]
for(let i in a){
    console.log(i)    //此时
}

image.png

此时的输出结果不仅输出了数组下标还输出了数组原型上的方法属性。那么怎么去除该方法属性呢。

利用hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。

显然数组a中是不具备方法contains和subYitle的,这两个方法只在原型链上。所以通过hasOwnProperty()我们能拿到数组它本身,其他不属于他自身的对象就不在。

Array.prototype.contains = function() { return null } 
Array.prototype.subTitle= 'Flutter'
let a = [1,2,3,4]
for(let i in a){
  if(a.hasOwnProperty(i))    //只有当他有自身指定属性才执行下面的语句
  //当是否含有contains方法时,返回false 那么也就不执行打印语句
  console.log(i)     //那么i就显示 数组a 的下标 0 1 2 3
}

本人是萌新小白,如果有说的不好的地方,希望大佬多多指正,感谢各位技术大牛。