for..of是ES6中引入的新特性,它主要的作用是:循環一個可迭代的對象。
它可以循環遍歷,數組、字符串、Set對象等等,先來看兩個簡單的例子:
遍歷字符串
let str = 'Hello' for (item of str) { console.log(item) // 會依次打印H e l l o }
遍歷數組
let arr = [1,2,3,4,5] for(arrItem of arr){ console.log(arrItem) // 會依次打印 1 2 3 4 5 }
遍歷對象
let obj = { x:10, y:20 } for(objItem of obj){ console.log(objItem) }
其實遍歷對象的時候,會報一個錯誤:“Uncaught TypeError: obj is not iterable” ,大概意思就是obj對象是一個不可迭代的對象,或者說它沒有迭代器。
怎么辦呢?那就給obj添加一個迭代器。
迭代器
接着上面的例子,我們給obj添加一個迭代器
obj[Symbol.iterator] = ()=>{
}
緊接着,我們要在方法里面去寫一下迭代規則,就是說,你想怎么去迭代這對象。這個方法需要返回一個next方法,next方法里面,又需要返回一個對象,
並且這個對象里面需要有"done"屬性,“done”的值為bool類型的值,它相當於一個條件(或者說是開關),
判斷是否需要繼續循環,值為true時,跳出循環;值為false繼續下一次循環;看個例子:
let obj = { x:10, y:20 } obj[Symbol.iterator] = ()=> { return { next(){ return { done: false,
value:2
} } } } for(objItem of obj){ console.log(objItem) }
上面這個例子,第一次循環的時候,返回{done:false,value:2},打印“2”,第二次、第三次.... done的值一直是false,會出現死循環,一直打印“2”,
我們知道,如果要跳出循環,done的值要等於true,所以,我們可以加一些條件,當把對象遍歷完畢之后,跳出循環:
let obj = { x:10, y:20 } obj[Symbol.iterator] = ()=> { let keys = Object.keys(obj) //獲取對象的key值 let len = keys.length let n = 0 return { next(){ if (n<len){ //繼續循環 return { done: false, value: obj[keys[n++]] // 每次循環返回的值 } } else { // 跳出循環 return { done: true } } } } } for(objItem of obj){ console.log(objItem) // 依次打印 10 20 }
總結:常見的循環方法有,for循環、map()、forEach()、filter()等等,可以發現,每個方法都有自己的規則,比如返回值什么的。
那么,我們可以通過迭代器,去自定義循環規則,通過迭代器,返回自己想要的結果。