物件和陣列的遍歷

weixin_33766168發表於2017-01-20

陣列遍歷

1.普通for迴圈

程式碼如下

for(var i=0;i<arr.length;i++)
{
    //do something here
}

注:有待優化的空間

2.優化for迴圈

for(var i=0,len=arr.length;i<len;i++){
    //do something here
}

注:將長度快取起來,避免重複獲取,基本是效能最高的一種陣列遍歷方法。(在遍歷長度較多的陣列時,才會顯示優勢)

3. forEach迴圈

arr.forEach(function(el){
    //do something here
})

注:陣列自帶的方法

4. for in 方法

var arr=[2,3,4]
for(var item in arr){
    console.log(item)// 0,1,2
}

注:效率很低.該方法獲取的是鍵名。應用於array時,為下標index,應用到物件時,為key。下文提到的for of迴圈獲取到的是鍵值。

5. map方法

arr.map(function(item){
    //do something here
})

注:方式優雅,效率很低,還不如forEach

6. for of 迴圈(ES6)

for(var item of arr){
 // do something here
}

注:是ES6所支援的方法,凡是具有iterator介面的資料介面,都可以使用for of遍歷他的成員。其內部的實現方法是呼叫資料結構的Symbol.iterator 方法。for of迴圈的使用範圍包括:陣列,Set,Map,類陣列物件(如arguments物件,DOM Nodelist物件等),Generator物件,以及字串等

物件的屬性遍歷

關於物件的遍歷,主要是指其屬性的遍歷。以下總結6種方法來遍歷物件的屬性

1. for in

for in迴圈遍歷物件自身可繼承的 可列舉屬性(不包含Symbol屬性)

2. Object.keys(obj)

該方法返回一個陣列,包含物件自身的(不包含繼承的)所有可列舉的屬性(不包含Symbol屬性)

注:大多數情況下,我們只關心物件自身的屬性,引入繼承的屬性會讓問題 複雜化。所以儘量不要用for in迴圈而使用Object.keys()代替

3. Object.getOwnPropertyNames(obj)

包含物件自身的所有屬性(不包含Symbol屬性,但是包含不可列舉的屬性)

4. Object.getOwnPropertySymbols(obj)

返回一個陣列,包含物件自身的所有Sybmol屬性。

5. Reflect.ownKeys(obj)

返回一個陣列,包含物件自身的所有屬性,不管屬性名是否是Symbol或字串,也不管是否是可列舉的

6. Reflect.enumerate(obj)

與for in迴圈相同

擴充套件閱讀:屬性的可列舉性

描述

物件的每個屬性都有一個描述物件(Descriptor),用於描述該屬性的行為。

獲取方法

通過Object.getOwnPropertyDescriptor方法可以獲取該屬性的描述物件

var a={A:1}
Object.getOwnPropertyDescriptor(a,"A");
//{
//    configurable:true,
//    enumerable:true,可列舉性,true
//    value:1,
//    writable:true
//}

引入目的

當改屬性為false時,標示某些操作會忽略這個屬性:

  1. for in 迴圈

  2. Object.keys()

  3. JSON.stringify()

  4. Object.assign()

  5. Reflect.enumerate()

實際上,引入改屬性的目的,就是為了讓某些屬效能夠規避掉for in迴圈
另外,ES6種規定,所有Class原型上的方法都是不可列舉的。

參考文獻:
阮一峰:《ES6標準入門》

相關文章