1.for语句
for语句的语法结构如下:
for(initialize; test; increment) {
statement
}
initialize,test,increment三个值需要用分号分开。它们分别表示初始化操作,循环条件判断,计数器变量更新。statement则是在循环中需要执行的语句。
1)常见用法
for (let i = 0; i < 10; i++) {
console.log(i)
}
2)多语句用法
每一步操作都可以执行多个语句。
for (let i = 0, j = 0; i < 10 && j < 5; i++, j++) {
console.log(i, j)
}
3)缺省用法
可以省略任意操作,但两个分号不能省略。
let k = 0
for (; k < 5; k++) {
console.log(k)
}
而且省略test操作时,程序会陷入死循环:
for (; ;) {
console.log(1)
}
4)循环变量非数字
遍历链表等数据结构时非常有用:
// o是链表的头结点
for (; o.next; o = o.next) {
// 操作
}
2.for/in语句
for/in语句的语法结构如下:
for(variable in object) {
statement
}
variable:必须是一个适用于赋值表达式左侧的值
- 变量名。
- 通过var、let、const等关键字声明的变量。
- 可以产生左值的表达式。
object:是一个表达式,其计算结果为一个对象。
遍历对象属性成员
let object = {
name: '张三',
age: 25
}
for (const key in object) {
console.log(key)
}
执行流程
104
首先执行object表达式。
若其结果为null或undefined,则跳过该循环。
若其结果为原始值(基本数据类型的值,如:Number、String、Symbol、Boolean),这个原始值将会转化为与之对应的包装对象。
包装对象
下面是一个String类型的数据调用的slice方法属性。
为什么String类型的数据不是对象,但却可以使用对象的访问形式呢?
只要引用了字符串s中的属性,javascript就会将字符串值通过new String(s)的方法转换为对象,这个对象继承了字符串的方法,并被用来处理属性的引用。Boolean、Number类型的数据同上。
console.log('string'.slice(0, 4)) // stri
variable是个表达式
let o = { x: 1, y: 2, z: 3 }
let a = [], i = 0
for (a[i++] in o) {
console.log(a)
}
遍历范围
for/in语句不会遍历对象的所有属性,只有“可枚举”的属性才会遍历到。
for/in语句会遍历整个原型链上所有可枚举的属性,所以性能会非常差,不推荐使用。
虽然该语句也可以遍历数组,但是同样也会返回数组中所有可枚举的属性,包括原型链上可枚举的属性。
3.for/of语句
ES6新增的语句。
for/of语句的语法结构:
for(varibale of Iterator) {
statement
}
遍历数组
以下两种方法是等价的:
const arr = ['one', 'two', 'three']
let iterator = arr[Symbol.iterator]()
for (let v of iterator) {
console.log(v)
}
for (let v of arr) {
console.log(v)
}
遍历范围
for/of语句可以遍历对象(不推荐)、数组、类数组对象(arguments和Dom nodeList对象)、字符串、Set、Map、Generator对象。
遍历对象时,获取的是对象的键值。遍历数组时,获取的是下标对应的值。
4.for in与for of的区别?
for…in获取的是对象的键名。for…of遍历获取的是对象的键值;
for…in会遍历对象的整个原型链,性能非常差不推荐使用。
for…of只遍历当前对象不会遍历原型链;
对于数组的遍历,for…in会返回数组中所有可枚举的属性(包括原型链上可枚举的属性)。
for…of只返回数组的下标对应的属性值;
总结:
for…in循环主要是为了遍历对象而生,不适用遍历数组; for…of循环可以用来遍历数组、类数组对象、字符串、Set、Map以及Generator对象