循环语句
语句/方法 | 描述 |
---|---|
while | 当条件语句为 true 时,执行语句块。 |
do … while | 执行一个语句块,在条件语句为 true 时继续执行该语句块。 |
for | 在条件语句为 true 时,可以将代码块执行指定的次数。 |
for … in | 用于遍历数组或者对象的属性(对数组或者对象的属性进行循环操作)。 |
for … of 6️⃣ | 遍历数组。 |
break | 退出switch语句或循环。 |
continue | 在循环中跳过当前的迭代,并继续循环中的下一个迭代。 |
forEach() | 数组的方法。用于调用数组的每个元素,并将元素传递给回调函数。不能break,ie9及以上 |
map() | 数组的方法。通过指定函数处理数组的每个元素,并返回处理后的数组。ie9及以上 |
return | 退出函数并返回函数的值。 |
一、while 语句
while
语句只要指定条件为 true,就会执行循环。
1、语法
while (condition) {
// 要执行的代码块
}
2、参数
参数 | 描述 |
---|---|
condition | 必须。定义执行循环的条件。如果返回 true,循环会继续执行,如果返回 false,循环会停止。注意: ➤ 如果你的条件一直为 true,该循环永远不会结束,并会导致浏览器崩溃。 ➤ 如果 condition 是变量,请在循环开始前初始化变量,并让它在循环中自增长,如果你忘记设置变量自增长,可能会出现无限循环的情况, 浏览器会崩溃。 |
3、实例
// 删除不合法的值
function removeWrongful(array) {
var i = array.length
while (i--) {
var item = array[i]
if (item === null || item === undefined || item === '') {
array.splice(i, 1)
}
}
}
二、do/while 语句
do/while
语句,同样当指定的条件为 true 时循环指定的代码块,但该语句会在条件判断前先执行一次。
1、语法
do {
// 要执行的代码块
}
while (condition);
2、参数和关键字
参数 | 描述 |
---|---|
condition | 必须。定义执行循环的条件。如果返回 true,循环会再次执行,如果返回 false,循环结束。 |
do语句 | 循环执行的代码块,该语句会在条件判断前先执行一次。注意:如果 condition 是变量,请在循环开始前初始化变量,并让它在循环中自增长,如果你忘记设置变量自增长,可能会出现无限循环的情况, 浏览器会崩溃。 |
3、示例
var arr = ['3','12','64']
var i = 0;
do {
arr[i] ++;
i++;
}
while (i < arr.length)
console.log(arr) // [4, 13, 65]
三、for 语句
for
语句只要判断条件为 true 就会一直执行,直到条件为 false。
1、语法
for (statement1; statement2; statement3) {
// 要执行的代码块
}
2、参数
参数 | 描述 |
---|---|
statement1 | 用于变量的初始化,在循环之前执行。初始化多个变量使用, 隔开。可选(比如把变量声明在外部) |
statement2 | 用于循环的条件判断。如果条件为 true,循环会继续执行,如果为 false,循环终止。可选(如果忽略,则必须在循环内提供 break,否则循环就无法停下来) |
statement3 | 用于自增或自减计数变量,在每次循环后执行该语句。可选(比如当循环内部有相应的代码时) |
3、示例
基本演示
var arr = [3, 12, 64]
for(var i=0, len=arr.length; i<len; i++) {
arr[i] ++;
}
console.log(arr) // [4, 13, 65]
省略相关参数(建议不使用,因为语意性较差)
var arr = [3, 12, 64]
var i=0, len=arr.length
for(; i<len; ) {
arr[i] ++;
i++
}
console.log(arr) // [4, 13, 65]
4、性能优化
如上,变量的 len
的赋值要写在 statement1
中,如果放在 statement2
条件语句中的话,每次循环都将会调取 arr
的迭代器来读取 length
的值,会降低性能。
四、for/in 语句
for/in
语句用于循环对象属性。
1、语法
for (var variable in object) {
// 执行的代码块
}
2、参数
参数 | 描述 |
---|---|
variable | 必须。指定的变量可以是数组的索引,也可以是对象的属性。 |
object | 必须。指定迭代的的对象。 |
3、遍历规则
for in 不会读取不可枚举属性,如数组的length属性。
for in 在循环对象的属性时也会遍历原型链。如下:
// 扩展 Object.prototype
Object.prototype.bar = 100;
var obj = { a: 3, b: 12, c: 64 }
for (var key in obj) {
console.log(key) // 'a', 'b', 'c', 'bar'
obj[key]++
}
console.log(obj) // { a: 4, b: 13, c: 65, bar: 101}
可以使用 hasOwnProperty
检测某个对象是否拥有某个属性,这样可以有效避免扩展本地原型而引起的错误。
var obj = { a: 3, b: 12, c: 64 }
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
console.log(key) // 'a', 'b', 'c'
obj[key]++
}
}
console.log(obj) // { a: 4, b: 13, c: 65 }
5、for/in 遍历数组的问题
for … in
循环由于历史遗留问题,它遍历的实际上是对象的属性名称。当他遍历数组时,会存在一下问题:
-
遍历顺序有可能不是按照实际数组的内部顺序。
-
遍历出来的索引值为字符串。
-
for in 会遍历数组所有的可枚举属性,包括原型(length除外)。如下:
var arr = ['A', 'B', 'C']; arr.name = 'Hello'; for (var x in arr) { console.log(x); // '0', '1', '2', 'name' }
for … of
循环则没有这些问题,它更适合遍历数组。参考下一点。
五、for/of 语句
for/of
语句,遍历array、string、map、set等拥有迭代器对象的集合,不能遍历对象。ES6新增
1、语法
for (var variable of array) {
// 执行的代码块
}
2、参数
参数 | 描述 |
---|---|
variable | 必须。指定的变量可以是数组每一项的值。改变该值时不会改变原数组,当该值是对象时可以改变属性的值 |
array | 必须。指定迭代的的数组。 |
3、示例
var arr = [3, 12, 64]
for (var v of arr) {
console.log(v) // 3, 12, 64
v++
}
console.log(arr) // 不变 [3, 12, 64]
4、for/of 遍历对象的问题
可以使用 Object.keys()
var obj = { name: 'guang', age: '25' }
var keys = Object.keys(obj)
for (var k of keys) {
console.log(k) // "name", "age"
}
六、forEach 方法
forEach()
方法用于调用数组的每个元素,并将元素传递给回调函数。对于空数组是不会执行回调函数的。
1、语法
array.forEach(function(currentValue, index, arr), thisValue)
2、参数
参数 | 描述 |
---|---|
function(currentValue, index,arr) | 必须。函数,数组中的每个元素都会执行这个函数。函数参数: currentValue :必须。当前元素的值 index :可选。当前元素的索引值 arr :可选。当前元素属于的数组对象 |
thisValue | 可选。传递给函数的值一般用 “this” 值。如果这个参数为空, “undefined” 会传递给 “this” 值 |
3、实例
var arr = [
{ id: 'a', count: 56 }
]
arr.forEach(function(item, i) {
item.count += 1
})
console.log(arr) // [ { id: 'a', count: 37, id: 'b', count: 57 } } ]
七、map 方法
map
方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。不会对空数组进行检测。
1、语法
array.map(function(currentValue,index,arr), thisValue)
2、参数
参数 | 描述 |
---|---|
function(currentValue, index,arr) | 必须。函数,数组中的每个元素都会执行这个函数。函数参数: currentValue :必须。当前元素的值 index :可选。当前元素的索引值 arr :可选。当前元素属于的数组对象 |
thisValue | 可选。对象作为该执行回调时使用,传递给函数,用作 “this” 的值。如果省略了 thisValue,或者传入 null、undefined,那么回调函数的 this 为全局对象。 |
3、实例
var arr = [
{ id: 'a', count: 36 },
{ id: 'b', count: 56 }
]
var newArr = arr.map(function(item, i) {
return item.count + 1
})
console.log(arr) // 不变 [ { id: 'a', count: 36, id: 'b', count: 56 } ]
console.log(newArr) // [ 37, 57 } ]
// 不return,用法和forEach一样
var arr = [
{ id: 'a', count: 36 },
{ id: 'b', count: 56 }
]
arr.map(function(item, i) {
item.count += 1
})
console.log(arr) // [ { id: 'a', count: 37, id: 'b', count: 57 } } ]
八、break | continue 语句
break
语句:用于退出 switch 语句或循环语句。
while
do … while
for
for … in
for … of
continue
语句:用于跳出当前的迭代,并开始下一次迭代。
while
do … while
for
for … in
for … of
实例
var arr = [3, 12, 64]
for (var i = 0; i < arr.length; i++) {
arr[i]++
if (i === 1) break
}
console.log(arr) // [4, 13, 64]
var arr = [3, 12, 64]
for (var i = 0; i < arr.length; i++) {
if (i === 1) continue
arr[i]++
}
console.log(arr) // [4, 12, 65]
九、性能优化
定义一个数组
var index = 0;
var arr = [];
while (index < 5000000) {
arr.push(index);
index++;
}
1、循环语句性能比较
for of
:11.89990234375ms
console.time('for of');
for(var v of arr){
v++
}
console.timeEnd('for of'); // for of: 11.89990234375ms
for
:7.205078125ms
console.time('for');
for (var i = 0; i < arr.length; i++) {
arr[i]++
}
console.timeEnd('one'); // for: 7.205078125ms
如上,for
循环的性能要好于 for of
,至于 while
do while
性能和 for
循环相当。
2、for循环性能优化
for
(优化后的 ):3.3369140625ms
console.time('for');
for (var i = 0, len = arr.length; i < len; i++) {
arr[i]++
}
console.timeEnd('for'); // for: 3.3369140625ms