for-in 和 for-of 的區別
1. for-in迴圈
for-in迴圈主要用於遍歷物件,for()中的格式:for(keys in zhangsan){}
keys表示obj物件的每一個鍵值對的鍵!!所有迴圈中,需要使用obj[keys]來取到每一個值!!!for-in 迴圈,遍歷時不僅能讀取物件自身上面的成員屬性,也能延續原型鏈遍歷出物件的原型屬性所以,可以使用hasOwnProperty判斷一個屬性是不是物件自身上的屬性obj.hasOwnProperty(keys)==true 表示這個屬性是物件的成員屬性,而不是原先屬性。
//宣告一個Peson類
function Person(){
this.name = "張三" ;
this.age = 14;
this.func1 = function(){
}
}
//例項化這個類
var zhangsan = new Person();
//使用for-in遍歷這個物件
for(keys in zhangsan){
console.log(zhangsan[keys])
}
2. for-of迴圈
ES6 借鑑 C++、Java、C# 和 Python 語言,引入了for…of迴圈,作為遍歷所有資料結構的統一的方法。
一個數據結構只要部署了Symbol.iterator屬性,就被視為具有iterator介面,就可以用for…of迴圈遍歷它的成員。也就是說,for…of迴圈內部呼叫的是資料結構的Symbol.iterator方法。
for…of迴圈可以使用的範圍包括陣列、Set 和 Map 結構、某些類似陣列的物件(比如arguments物件、DOM NodeList 物件)、後文的 Generator 物件,以及字串
1. 陣列
var arr = ['a', 'b', 'c', 'd'];
for (let a in arr) {
console.log(a); // 0 1 2 3
}
for (let a of arr) {
console.log(a); // a b c d
}
上面程式碼表明,for…in迴圈讀取鍵名,for…of迴圈讀取鍵值。如果要通過for…of迴圈,獲取陣列的索引,可以藉助陣列例項的entries方法和keys方法
2.Set 和 Map 結構
var engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]);
for (var e of engines) {
console.log(e);
}
// Gecko Trident Webkit
var es6 = new Map();
es6.set("edition", 6);
es6.set("committee", "TC39");
es6.set("standard", "ECMA-262");
for (var [name, value] of es6) {
console.log(name + ": " + value);
}
// edition: 6
// committee: TC39
// standard: ECMA-262
上面程式碼演示瞭如何遍歷 Set 結構和 Map 結構。值得注意的地方有兩個,首先,遍歷的順序是按照各個成員被新增進資料結構的順序。其次,Set 結構遍歷時,返回的是一個值,而 Map 結構遍歷時,返回的是一個數組,該陣列的兩個成員分別為當前 Map 成員的鍵名和鍵值。
3.類似陣列的物件
類似陣列的物件包括好幾類。下面是for…of迴圈用於字串、DOM NodeList 物件、arguments物件的例子。
// 字串
var str = "hello";
for (let s of str) {
console.log(s); // h e l l o
}
// DOM NodeList物件
let paras = document.querySelectorAll("p");
for (let p of paras) {
p.classList.add("test");
}
// arguments物件
function printArgs() {
for (let x of arguments) {
console.log(x);
}
}
printArgs('a', 'b');// 'a' 'b'
與其他遍歷語法的比較
for…in迴圈有幾個缺點
①陣列的鍵名是數字,但是for…in迴圈是以字串作為鍵名“0”、“1”、“2”等等。
②for…in迴圈不僅遍歷數字鍵名,還會遍歷手動新增的其他鍵,甚至包括原型鏈上的鍵。
③某些情況下,for…in迴圈會以任意順序遍歷鍵名。
for…in迴圈主要是為遍歷物件而設計的,不適用於遍歷陣列。for…of迴圈
有著同for…in一樣的簡潔語法,但是沒有for…in那些缺點。
不同於forEach方法,它可以與break、continue和return配合使用。
提供了遍歷所有資料結構的統一操作介面