多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## **19.for in 和 for of** 1、for in * 1.一般用于遍历对象的可枚举属性。以及对象从构造函数原型中继承的属性。对于每个不同的属性,语句都会被执行。 * 如果不想遍历原型方法和属性的话,可以在循环内部判断一下,hasOwnPropery方法可以判断某属性是否是该对象的实例属性。 * 2.不建议使用 for in 遍历数组,因为输出的顺序是不固定的。 * 3.如果迭代的对象的变量值是 null 或者 undefined, for in 不执行循环体,建议在使用 for in 循环之前,先检查该对象的值是不是 null 或者 undefined 2、for of--遍历数组的值, 而不是索引, 不会遍历原型 * 1.for…of 语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句 `forEach`不支持`break, continue, return`等 ``` var s = { a: 1, b: 2, c: 3 }; var s1 = Object.create(s); for (var prop in s1) { console.log(prop); //a b c console.log(s1[prop]); //1 2 3 } for (let prop of s1) { console.log(prop); //报错如下 Uncaught TypeError: s1 is not iterable } for (let prop of Object.keys(s1)) { console.log(prop); // a b c console.log(s1[prop]); //1 2 3 } ``` ## for ,forEach, for-in ,for-of 的区别 [参考博客](https://blog.csdn.net/weixin_33862514/article/details/88630047) for...of 循环是遍历所有数据结构的统一的方法。for...of循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、Generator 对象,以及字符串。 ###### 情况1:非数字的属性 forEach用来遍历数组,局限 不能中断循环(使用break语句或使用return语句)。 for-in循环实际是为循环”enumerable“对象而设计的,for - in 也可用来循环数组,但一般并不推荐 ```javascript let obj = {a: '1', b: '2', c: '3', d: '4'} for (let o in obj) { console.log(o) //遍历的实际上是对象的属性名称 a,b,c,d console.log(obj[o]) //这个才是属性对应的值1,2,3,4 } ``` 只有 for-in 循环才能够打印出这个键值对 ###### 情况2:数组空值 假设要遍历的数组张这样:array = ['a', , 'c'],只有 forEach 和 for-in 遍历会**跳过空值**, 如果空值明确设置为 undefined 如 ['a', undefined, 'c'] 那么所有遍历方法都能够将 undefined 遍历出来 在 JSON 中是不支持这样的空值的,如果在 parse 方法调用时传入的 JSON 字符串数据含有空值,会报错 ```javascript JSON.parse('["a", , "c"]') // 所以建议使用 for-of 或 for 循环进行遍历 ``` stringify 方法调用时,空值会被转为 null 非空值或 undefined ###### 情况3:方法 this 指向的上下文 在 forEach 中需要传入一个函数,这个函数的 this 指向因语法形式而变化 只有 forEach 在传入非箭头函数的时候会出现不一致的情况,建议使用箭头函数 ###### 情况4:Async/Await async 异步编程中 forEach 则不会按照预期执行 ```javascript // 语法错误 {(async () => { array.forEach(element => { // 改正: async element => {...} 并行执行 const result = await new Promise(res => setTimeout(() => { res(element) }, 1000)) console.log(result) }) })()} ``` forEach 的原理:本质上 forEach 就像一个 for 循环的包装 但是: 在回调函数内部调用 await 需要这个回调函数本身也是 async 函数,