for...in语句
遍历对象属性名称
for...in
语句可用于遍历对象属性名称。对于下列对象:
let obj = {
name: 'sarkuya',
age: 25,
showAge: function() {
return this.age;
}
};
遍历该对象的所有属性名称:
for (let propName in obj) {
console.log(propName);
}
显示:
name
age
showAge
有了属性名称,可使用obj[propName]
来访问属性值。
for (let propName in obj) {
console.log(obj[propName]);
}
显示:
sarkuya
25
function () {
return this.age;
}
可使用typeof obj[propName]
语句来查看各个属性值的类型:
for (let propName in obj) {
console.log(typeof obj[propName]);
}
显示:
string
number
function
分类显示:
let funcNames = [];
let otherPropNames = [];
for (let propName in obj) {
if (typeof obj[propName] === 'function') {
funcNames.push(propName);
} else {
otherPropNames.push(propName);
}
}
console.log(otherPropNames);
console.log(funcNames);
显示:
["name", "age"]
["showAge"]
遍历数组
当for...in
语句用于数组时,表示数组索引值的字符串将作为属性名称。
let arr = ['a', 'b', 'c'];
for (let propName in arr) {
console.log(propName); // 0, 1, 2
console.log(typeof propName); // "string"
}
需特别注意:
- 不要误认为数据类型为整数的数组索引值是属性名称;
- 不要误认为
for...in
语句可以遍历数组元素。
如果需要遍历数组元素,使用for...of
语句。
let arr = [5, 10, 15];
for (let element of arr) {
console.log(element); // 5, 10, 15
}
遍历字符串
当for...in
语句用于字符串时,由于字符串是字符的数组,因此表示数组索引值的字符串将作为属性名称。
let str = 'Hello';
for (let propName in str) {
console.log(propName); // 0, 1, 2, 3, 4
}
使用for...of
语句遍历字符串中的字符:
let str = 'Hello';
for (let char of str) {
console.log(char); // H, e, l, l, o
}
容易踩雷的地方
许多时候,我们可能认为for...in
语句只用于遍历对象的属性名称,但它还可能用在数组及字符串上面,只不过此时属性名称变为元素索引值的字符串。
当我们使用递归函数时,就很容易踩到此雷。
let obj = {
person: {
name: 'sarkuya',
age: 25
}
};
myTrasverseTest(obj);
function myTrasverseTest(obj) {
if (typeof (obj) === 'string') {
return;
}
for (let propName in obj) {
console.log(propName);
console.log(obj[propName]);
myTrasverseTest(obj[propName]);
}
}
这里的雷是对于字符串,即使只有一个字符如"s",代码:
for (let propName in "s") {
myTrasverseTest(obj[propName]);
}
都会造成无何止地调用递归函数。因此,当for...in
语句用于字符串时,必须终止递归。