您的当前位置:首页正文

for-in和for-of

2024-11-30 来源:个人技术集锦

参考:

for in 和 for of 相对于大家肯定都不陌生,都是用来遍历属性的没错。那么先看下面的一个例子:

例1:

以上是遍历对象,下面再看一个遍历数组的例子。

var arr = [1,3,5]

//for-in循环
for(let i in arr) {
    console.log(i);
    //0
    //1
    //2
}

//for-of循环
for(let i of arr){
    console.log(i);
    //1
    //3
    //5
}

以上代码是对一个数组进行遍历, for in 返回的值为 0、1、2,这是数组的下标

而 for of 返回的是1,3,5

 

例2

var arr = [1,3,5]
arr.name = 'single'


for(let i in arr) {
    console.log(i);
    //0
    //1
    //2
    //name
}

for(let i of arr){
    console.log(i);
    //1
    //3
    //5
}

for in 循环可以遍历出 name 这个键名

 

例3

var obj = {
    name:'张三',
    age: 18,
    sex: "男"
}

for(let i in obj) {
    console.log(i);
    //name
    //age
    //sex
}

for(let i of obj){
    console.log(i);
    //TypeError: obj is not iterable at Object.
}

 

例4

var obj = {
    name:'张三',
    age: 18,
    sex: "男"
}
obj.score = 97.5

for(let i in obj) {
    console.log(i);
    //name
    //age
    //sex
    //score
}

for(let i of obj){
    console.log(i);
    //TypeError: obj is not iterable at Object.
}

以上代码通过 for in 和 for of 对一个obj对象进行遍历,for in 正常的获取了对象的 key值,而 for of却报错了。

for in 的特点

结合上面的两个例子,分析得出:

  • for ... in 循环返回的值都是数据结构的 键名。如——例1,例3

  • 遍历对象返回的对象的key值,遍历数组返回的数组的下标(key)。

  • for ... in 循环不仅可以遍历数字键名,还会遍历原型上的值和手动添加的其他键。如——例2

  • 特别情况下, for ... in 循环会以任意的顺序遍历键名

 

for of 特点

  • for of 循环用来获取一对键值对中的键值。如——例1,例3

  • 一个数据结构只要部署了 Symbol.iterator 属性, 就被视为具有 iterator接口, 就可以使用 for of循环。

    例3这个对象,没有 Symbol.iterator这个属性,所以使用 for of会报 obj is not iterable

 

哪些数据结构部署了 Symbol.iteratoer属性了呢?

只要有 iterator 接口的数据结构,都可以使用 for of循环。

  • 原生具备 Iterator 接口的数据结构如下。

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

以上这些都可以直接使用 for of 循环。 凡是部署了 iterator 接口的数据结构也都可以使用数组的 扩展运算符(...)、和解构赋值等操作。

我也想让对象可以使用 for of循环怎么办?

方法1:使用 Object.keys() 获取对象的 key值集合后,再使用 for of

以例1为例

var obj = {
    name:'张三',
    age: 18,
    sex: "男"
}


for(let i of Object.keys(obj)){
    console.log(i);
    //name
    //age
    //sex
}

方法2:也可以给一个对象部署 Symbol.iterator属性

let obj={
    name:'张三',
    age: 18,
    sex: "男"
}

function* objectEntry(obj) {
    let newObj = Reflect.ownKeys(obj)

    for(let i of newObj) {
        yield [i,obj[i]]
    }
}


for(let i of objectEntry((obj))) {
    console.log(i);
}
function* objectEntries() {
    // let propKeys = Object.keys(this);
    let propKeys = Reflect.ownKeys(this);

    for (let i of propKeys) {
        yield [i, this[i]];
    }
}

let obj={
    name:'张三',
    age: 18,
    sex: "男"
}
obj[Symbol.iterator] = objectEntries


for(let i of obj) {
    console.log(i);
}


注:Reflect.ownKeys方法用于返回对象的所有属性,基本等同于Object.getOwnPropertyNamesObject.getOwnPropertySymbols之和。

 

显示全文