大家好,我是wo不是黃蓉牢酵,今年學(xué)習(xí)目標(biāo)從源碼共讀開始悬包,希望能跟著若川大佬學(xué)習(xí)源碼的思路學(xué)到更多的東西。
forEach 馍乙、for ... in 布近、for ... of有什么區(qū)別
forEach 數(shù)組提供的方法,只能遍歷數(shù)組
遍歷數(shù)組:for...in
key
返回?cái)?shù)組下標(biāo)丝格;for...of
key
返回值撑瞧;
遍歷對象:for...in
key
返回對象的鍵;for...of
遍歷對象報(bào)錯(cuò)显蝌,提示沒有實(shí)現(xiàn)person對象不可迭代预伺;
iterable
什么是可迭代對象?
簡單來說就是可以使用for...of
遍歷的對象曼尊,也就是實(shí)現(xiàn)了[Symbol.iterator]
迭代和循環(huán)有什么區(qū)別酬诀?
遍歷強(qiáng)調(diào)把整個(gè)數(shù)據(jù)依次全部取出來,是訪問數(shù)據(jù)結(jié)構(gòu)的所有元素骆撇;
迭代雖然也是一次取出數(shù)據(jù)瞒御,但是并不保證取多少,需要調(diào)用next
方法才能獲取數(shù)據(jù)神郊,不保證把所有的數(shù)據(jù)取完葵腹,是遍歷的一種形式高每。
有哪些對象是可迭代對象呢?
原生的可迭代對象 set map nodelist arguments 數(shù)組 string
迭代器是針對某個(gè)對象的践宴,有些對象是自己繼承了Symbol.Iterator鲸匿,也可以實(shí)現(xiàn)自己的迭代器,必須要實(shí)現(xiàn)一個(gè)next方法阻肩,返回內(nèi)容
{value:any,done:boolean}
實(shí)現(xiàn)對象的迭代器
如果要實(shí)現(xiàn)迭代器带欢,需要實(shí)現(xiàn)[Symbol.Iterator]
是一個(gè)函數(shù),這個(gè)函數(shù)返回一個(gè)迭代器
// let arr = ['a', 'b', 'c']
let person = {
name: 'a',
age: 18,
myIterator: function () {
var nextIndex = 0
return {
next: () => {
const array = Object.values(this)
return nextIndex < array.length
? { value: array[nextIndex++], done: false }
: { value: undefined, done: true }
}
}
}
}
let myIterator = person.myIterator()
console.log(person.myIterator())//{ next: [Function: next] }
console.log(myIterator.next())//{ value: 'a', done: false }
console.log(myIterator.next())//{ value: 18, done: false }
console.log(myIterator.next())//{ value: [Function: myIterator], done: false }
console.log(myIterator.next())//{ value: undefined, done: true }
{ value: undefined, done: true }
按道理實(shí)現(xiàn)了迭代器該對象就會(huì)變?yōu)榭傻鷮ο罅丝揪梢允褂?code>for..of遍歷
但是執(zhí)行后發(fā)現(xiàn)還是會(huì)提示Person不是可迭代的乔煞,是因?yàn)?code>for..of只能遍歷實(shí)現(xiàn)了[Symbol.iterator]
接口的的對象,因此我們寫的方法名要使用[Symbol.iterator]
修改后:
let person = {
name: 'a',
age: 18,
[Symbol.iterator]: function () {
var nextIndex = 0
return {
next: () => {
const array = Object.values(this)
return nextIndex < array.length
? { value: array[nextIndex++], done: false }
: { value: undefined, done: true }
}
}
}
}
//for..in
for (let key in person) {
console.log(key, person[key])
}
//for...of
for (let key of person) {
console.log(key)
}
//打印結(jié)果
name a
age 18
a
18
什么時(shí)候會(huì)用迭代器柒室?
應(yīng)用場景:可以參考阮一峰老師列舉的例子
js語法:for ... of 展開運(yùn)算符 yield 解構(gòu)賦值
創(chuàng)建對象時(shí):new map new set new weakmap new weakset
一些方法的調(diào)用:promise.all promise.race array.from
for in 和for of 迭代器渡贾、生成器(generator)
迭代器中斷:
迭代器中定義return
方法在迭代器提前關(guān)閉時(shí)執(zhí)行,必須返回一個(gè)對象
break return throw 在迭代器的return 方法中可以捕獲到
let person = {
name: 'a',
age: 18,
[Symbol.iterator]: function () {
var nextIndex = 0
return {
next: () => {
const array = Object.values(this)
return nextIndex < array.length
? { value: array[nextIndex++], done: false }
: { value: undefined, done: true }
},
return: () => {
console.log('結(jié)束迭代')
return { done: true }
}
}
}
}
//for...of
for (let key of person) {
console.log(key)
if (key === 'a') break
}
//打印結(jié)果
a
結(jié)束迭代
結(jié)束:下節(jié)講生成器