【JavaScript编程】循环语句及性能优化

循环语句


语句/方法 描述
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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章