JS中的for...in和for...of有什么区别?
你好,我是沐爸,欢迎点赞、收藏、评论和关注。
在 JavaScript 中,for...in
和 for...of
是两种用于遍历数组(或其他可迭代对象)的循环语句,但它们之间存在显著的差异。
一、遍历数组
for…in
const arr = ['apple', 'banana', 'cherry']
for (const index in arr) {
console.log(index, arr[index])
}
// 0 apple
// 1 banana
// 2 cherry
遍历数组的索引,访问数组元素通过 arr[index]
形式。
for…of
const arr = ['apple', 'banana', 'cherry']
for (const value of arr) {
console.log(value)
}
// apple
// banana
// cherry
遍历数组元素,不能访问索引。
二、遍历对象
for...inconst obj = {
name: '张三',
age: 20
}
for (const key in obj) {
console.log(key, obj[key])
}
// name 张三
// age 20
遍历对象的键(key),通过obj[key]
访问属性的值。
for…of
const obj = {
name: '张三',
age: 20
}
for (const key of obj) {
console.log(key)
}
// TypeError: obj is not iterable
for...of
循环默认并不支持直接遍历对象的属性。因为for...of
循环是为可迭代对象(如Array, Map, Set, arguments等)设计的,这些对象都有一个[Symbol.iterator]
方法。
所以,常见的做法是结合 Object.keys()
、Object.values
或者Object.entries()
进行遍历。
const obj = {
name: '张三',
age: 20
}
for (const key of Object.keys(obj)) {
console.log(key, obj[key])
}
// name 张三
// age 20
for (const value of Object.values(obj)) {
console.log(value)
}
// 张三
// 20
for (const [key, value] of Object.entries(obj)) {
console.log(key, value)
}
// name 张三
// age 20
另外,for…in 和 for…of 在遍历对象原型上的属性也有区别,for…in 会遍历对象原型上的属性,for…of 不会。
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.say = function() {
console.log('My Name is ' + this.name)
}
const obj = new Person('张三', 20)
for (const key in obj) {
console.log(key, obj[key])
}
// name 张三
// age 20
// say [Function (anonymous)]
for (const key of Object.keys(obj)) {
console.log(key, obj[key])
}
// name 张三
// age 20
说准确点,并不是 for…of 不会遍历对象原型上的属性,而是 for…of 借助的 Object.keys()
、Object.values
、Object.entries()
方法返回的数组只包含对象自身的属性和值。
如果想让 for…in 跟 for…of 一样只遍历对象自身的属性,可使用 hasOwnProperty
。
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key, obj[key])
}
}
三、遍历其他类型数据
1.字符串let str = "hello"
for (const index in str) {
console.log(index, str[index])
}
// 0 h
// 1 e
// 2 l
// 3 l
// 4 o
for (const value of str) {
console.log(value)
}
// h
// e
// l
// l
// o
2.Set 结构
const set = new Set(['apple', 'banana', 'cherry'])
for (const value in set) {
console.log(value) // 这里几乎不会执行任何有用的操作,因为set没有可枚举的属性
}
for (const value of set) {
console.log(value)
}
// 输出(顺序可能不同,因为Set是无序的):
// apple
// banana
// cherry
3.Map结构
const map = new Map([['a', 1], ['b', 2], ['c', 3]])
for (const value in map) {
console.log(value) // 这里几乎不会执行任何有用的操作,因为map没有可枚举的属性
}
for (const [key, value] of map) {
console.log(key, value)
}
// 输出:
// a 1
// b 2
// c 3
4.类数组arguments
function fn(a, b, c) {
for (const index in arguments) {
console.log(index, arguments[index])
}
// 0 zhangsan
// 1 20
// 2 男
for (const value of arguments) {
console.log(value)
}
// zhangsan
// 20
// 男
}
fn('zhangsan', 20, '男')
四、总结
通过以上示例可知,两者主要有以下区别:
for...in
:- 遍历对象的可枚举属性(包括原型链上的)
- 对于数组,遍历的是索引(字符串类型)。
- 不可遍历 Set 和 Map 结构
for...of
:- 遍历可迭代对象的值,直接访问值而不是键名或索引。
- 不可直接变量对象,需要借助 Object.keys/values/entries。
- 另外可遍历 Set 和 Map 结构
好了,分享结束,谢谢点赞,下期再见。