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