๐๋ฐ๋ณต์์ ์์ฑ์ 101 #1๐
40961 ๋จ์ด programmingwebdevjavascript
For ๋ฃจํ ๋ฌธ์
for ๋ฃจํ์ ๋ฌธ์ ์ ๊ณผ for-of ๋ฃจํ๋ฅผ ์ฌ์ฉํ ๊ฐ์น๊ฐ ์๋ ์ด์ ๋ฅผ ์ค๋ช
ํ๊ธฐ ์ ์ ์๋ ์ฝ๋๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
//I want to list all combinations of these three arrays
let colors = ["Red ", "Blue ", "Yellow "];
let cars = ["BMW ", "Audi ", "Fiat "];
let models = ["v1.", "v2.", "v3."];
let allOptionsForLoop = [];
let allOptionsForOfLoop = [];
//Let's use for loop to create allOptionsForLoop:
for(let i=0; i<colors.length; i++) {
for(let j=0; j<cars.length; j++) {
for(let k=0; k<models.length; k++) {
allOptionsForLoop.push(colors[i]+cars[j]+models[k]);
}
}
}
// And for-of loop to create allOptionsForOfLoop;
for(const color of colors) {
for(const car of cars) {
for(const model of models) {
allOptionsForOfLoop.push(color+car+model)
}
}
}
console.log(allOptionsForLoop)
console.log("_________________________")
console.log(allOptionsForOfLoop)
console.log(JSON.stringify(allOptionsForLoop)===JSON.stringify(allOptionsForOfLoop))
// [
'Red BMW v1.', 'Red BMW v2.',
'Red BMW v3.', 'Red Audi v1.',
'Red Audi v2.', 'Red Audi v3.',
'Red Fiat v1.', 'Red Fiat v2.',
'Red Fiat v3.', 'Blue BMW v1.',
'Blue BMW v2.', 'Blue BMW v3.',
'Blue Audi v1.', 'Blue Audi v2.',
'Blue Audi v3.', 'Blue Fiat v1.',
'Blue Fiat v2.', 'Blue Fiat v3.',
'Yellow BMW v1.', 'Yellow BMW v2.',
'Yellow BMW v3.', 'Yellow Audi v1.',
'Yellow Audi v2.', 'Yellow Audi v3.',
'Yellow Fiat v1.', 'Yellow Fiat v2.',
'Yellow Fiat v3.'
]
_________________________
[
'Red BMW v1.', 'Red BMW v2.',
'Red BMW v3.', 'Red Audi v1.',
'Red Audi v2.', 'Red Audi v3.',
'Red Fiat v1.', 'Red Fiat v2.',
'Red Fiat v3.', 'Blue BMW v1.',
'Blue BMW v2.', 'Blue BMW v3.',
'Blue Audi v1.', 'Blue Audi v2.',
'Blue Audi v3.', 'Blue Fiat v1.',
'Blue Fiat v2.', 'Blue Fiat v3.',
'Yellow BMW v1.', 'Yellow BMW v2.',
'Yellow BMW v3.', 'Yellow Audi v1.',
'Yellow Audi v2.', 'Yellow Audi v3.',
'Yellow Fiat v1.', 'Yellow Fiat v2.',
'Yellow Fiat v3.'
]
true
์ฐจ์ด์ ์ด ๋ณด์ด์๋์?
for-of ๋ฃจํ๋ฅผ ์ฌ์ฉํ๋ฉด ์ปฌ๋ ์
์ธ๋ฑ์ค๋ฅผ ๋ชจ๋ํฐ๋งํ ํ์๊ฐ ์์ ํ ์์ด์ ธ ์ปฌ๋ ์
์ฝํ
์ธ ์์
์ ์ง์คํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ for-of ๋ฃจํ๋ ์ฃผ์ด์ง ์ปฌ๋ ์
์ ๋ฐ๋ณตํ๋ ๋ฐฉ๋ฒ์ ์ด๋ป๊ฒ ์๋๊น?
๋ฐ๋ณต์
for-of ๋ฃจํ์ ์๋ ๋ฐฉ์์ ์์ ํ ์ดํดํ๊ธฐ ์ ์ ๋ฐ๋ณต์๋ฅผ ์ดํดํด์ผ ํฉ๋๋ค. ๋ฐ๋ณต์๋ ๋ฌด์์
๋๊น?
๋ฐ๋ณต์๋ ๋ฐ๋ณตํ๋๋ก ์ค๊ณ๋ ๋ค์ ํน์ดํ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง ๊ฐ์ฒด์
๋๋ค. ๋ฐ๋ณต์๋ ์ปฌ๋ ์
์์ ์์น๋ฅผ ์ถ์ ํ๋ ๋ด๋ถ ํฌ์ธํฐ์ ๊ฒฐ๊ณผ ๊ฐ์ฒด๋ฅผ ํฌํจํ๋ next()
๋ฉ์๋๋ฅผ ํฌํจํฉ๋๋ค. ๊ฒฐ๊ณผ ๊ฐ์ฒด์๋ ๋ ๊ฐ์ ๊ฐ{value, done}
์ด ์๊ณ , value์๋ ๋ฐ๋ณต์์ ๋ฐํ ๊ฐ์ด ํฌํจ๋๋ฉฐ, done์ ์ฃผ์ด์ง ๊ฐ์ด ๋ง์ง๋ง์ผ๋ก ๋ฐํ๋ ๊ฐ์ธ์งtrue
์๋์งfalse
์๋ ค์ค๋๋ค.
์ด ์ ๋ณด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ด๋ฌํ ๋ฐ๋ณต์๋ฅผ ์ง์ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
function myFirstIterator(itemsToIterate) {
// i is an "iteration pointer"
let i = 0;
return {
next: function() {
//check if itemsToIterate[i] exists
let done = i >= itemsToIterate.length;
//if its done return undefined
let value = !done ? itemsToIterate[i] : undefined;
//ok we've got {done, value} so lets move forward
i++;
return {
done,
value
}
}
}
}
let iterateMe = myFirstIterator(["Hello", "World", "!"]);
console.log("1. ", iterateMe.next()) // 1. { done: false, value: 'Hello' }
console.log("2. ", iterateMe.next()) // 2. { done: false, value: 'World' }
console.log("3. ", iterateMe.next()) // 3. { done: false, value: '!' }
console.log("4. ", iterateMe.next()) // 4. { done: true, value: undefined }
console.log("5. ", iterateMe.next()) // 5. { done: true, value: undefined }
๋ณด์๋ค์ํผ ์์ ์ค๋ช
๋ ๊ท์น(ES6์ ์ ์๋ ๊ท์น)์ ๋ฐ๋ผ ๋์ํ๋ ๋ฐ๋ณต์๋ฅผ ๋ง๋๋ ๊ฒ์ ์ฌ์ด ์ผ์ด ์๋๋๋ค. ๋คํํ๋ ES6์ด ๊ตฌ์ถ๋์ด ๋ฐ๋ณต์ ์์ฑ์ ๋ ์ฝ๊ฒ ํด์ฃผ๋ ์์ฑ๊ธฐ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด๋ป๊ฒ?
๋ฐ์ ๊ธฐ
๊ฐ๋จํ ๋งํด์ ์ ๋๋ ์ดํฐ๋ ๋ฐ๋ณต์๋ฅผ ๋ฐํํ๋ ํจ์์
๋๋ค. ์๋ ์ฝ๋๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
// * placed in front of myFisrstGenerator makes this function a generator
function *myFirstGenerator() {
//yield specifies the values that should be returned by the iterator when calling the next () method
yield "Hello";
yield "World";
yield "!"
}
let iterateMe = myFirstGenerator()
console.log("1. ", iterateMe.next()) // 1. { done: false, value: 'Hello' }
console.log("2. ", iterateMe.next()) // 2. { done: false, value: 'World' }
console.log("3. ", iterateMe.next()) // 3. { done: false, value: '!' }
console.log("4. ", iterateMe.next()) // 4. { done: true, value: undefined }
console.log("5. ", iterateMe.next()) // 5. { done: true, value: undefined }
๊ฐ yield ๋ช
๋ น ํ์ ์์ฑ๊ธฐ๋ ์์ฑ๊ธฐ ํจ์ ์คํ์ ์ค์งํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ฐ๋ณต์์ ์์๋ฅผ ์ถ๊ฐํ๋ ์์ฑ๊ธฐ๋ฅผ ๊ฐ๋ฐํ ์ ์์ต๋๋ค.
function *iterateMyArray(myArray) {
for(let i=0; i<myArray.length; i++) {
yield myArray[i]
}
}
let iterateMe = iterateMyArray(["Hello", "World", "!"])
console.log("1. ", iterateMe.next()) // 1. { done: false, value: 'Hello' }
console.log("2. ", iterateMe.next()) // 2. { done: false, value: 'World' }
console.log("3. ", iterateMe.next()) // 3. { done: false, value: '!' }
console.log("4. ", iterateMe.next()) // 4. { done: true, value: undefined }
console.log("5. ", iterateMe.next()) // 5. { done: true, value: undefined }
์ด์ ์์ฑ๊ธฐ* iterateMyArray()
๋ฅผ ์ฒ์๋ถํฐ ๋ฐ๋ณต์์ ๋น๊ตํฉ๋๋ค. ES5์ ๋น๊ตํ์ฌ ์ ๋๋ ์ดํฐ๋ก ES6 ๋ฐ๋ณต์๋ฅผ ์์ฑํ๋ ์ฉ์ด์ฑ์ ์ฐจ์ด๋ ์์ฒญ๋ฉ๋๋ค.
์ ๋๋ ์ดํฐ ํ๊ณผ ํธ๋ฆญ
์์ฑ๊ธฐ ๋ง๋ค๊ธฐ:
//โ
โ
โ
function* sampleGenerator() {}
//โ
โ
โ
function * sampleGenerator() {}
//โ
โ
โ
function *sampleGenerator() {}
//โ
โ
โ
function*sampleGenerator() {}
//โ
โ
โ
let sampleGenerator = function *() {}
//โ โ โ
let sampleGenerator = *() => {}
yield๋ฅผ ์ฌ์ฉํ ๋ ์ฃผ์ํ์ธ์.
//yield can be used only inside generators
//โ โ โ
function *newGen() {
function insideNewGen() {
//it will throw an error
yield "Hello"
}
}
์์ฑ๊ธฐ๋ฅผ ๊ฐ์ฒด ๋ฉ์๋๋ก ์ถ๊ฐํ ์ ์์ต๋๋ค.
let obj = {
//like this (ES5)โ
โ
โ
:
generatorNr1: function*(myArray) {
for(let i=0; i<myArray.length; i++) {
yield myArray[i]
}
},
//or like this (ES6)โ
โ
โ
:
*generatorNr2(myArray) {
for(let i=0; i<myArray.length; i++) {
yield myArray[i]
}
}
}
[Symbol.iterator]
ํ์ง๋ง for ๋ฃจํ๋ ์ด๋ป์ต๋๊น? ๋ฐ๋ณต์์ ์์ฑ๊ธฐ์ ๋ํ ์ฝ๋๊ฐ ๋๋ฌด ๋ง์ง๋ง for ๋ฃจํ์ ์ด๋ค ๊ด๋ จ์ด ์์ต๋๊น? ์ข์ ์ง๋ฌธ. ๋ฐ๋ณต์๋ ๋ฐ๋ณตํ๋ ์์, ์ฆ Symbol.iterator ๊ฐ์ฒด์ ์ฐ๊ฒฐ๋ฉ๋๋ค. ์ฃผ์ด์ง ๊ฐ์ฒด์ ๋ํ ๋ฐ๋ณต์๋ฅผ ๋ฐํํ๋ ํจ์๋ฅผ ์ง์ ํฉ๋๋ค. ๋ชจ๋ ๋ฐ๋ณต ๊ฐ๋ฅํ ์์์๋ ๊ธฐ๋ณธ Symbol.iterator๊ฐ ์ ์๋์ด ์์ต๋๋ค. ์ด ๋๋ถ์ for ๋ฃจํ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ฃจํ๊ฐ ๋ฐ๋ณต์ ๋ํ ์ง์์ ํ์๋ก ํ๋ ๋ฐ๋ณต์์ด๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ทธ๋ฌ๋ ๋ชจ๋ ์์์ ๊ทธ๋ฌํ ๊ธฐ๋ณธ ๋ฐ๋ณต์๊ฐ ์์ต๋๊น? ์ ๊ฒ ํด๋ณด์:
function doIhaveDefaultIterator(obj) {
return typeof obj[Symbol.iterator] === 'function'
}
//arrayโ
console.log(doIhaveDefaultIterator(["Hello", "World", "1"])) //true
//Mapโ
console.log(doIhaveDefaultIterator(new Map())) //true
//Stringโ
console.log(doIhaveDefaultIterator("hello")) //true
//Objectโ
console.log(doIhaveDefaultIterator(new Object())) //false
console.log(doIhaveDefaultIterator({})) //false
//Setโ
console.log(doIhaveDefaultIterator(new Set())) //true
//Weakmapโ
console.log(doIhaveDefaultIterator(new WeakMap)) //false
//WeakSetโ
console.log(doIhaveDefaultIterator(new WeakSet)) //false
์ฐ์. ๋ณด์๋ค์ํผ JS์ ๋ชจ๋ ๊ฒ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐ๋ณต๋ ์ ์๋ ๊ฒ์ ์๋๋๋ค. ํนํ ๊ฐ์ฒด์ ๋ฐ๋ณต์๊ฐ ์๋ ๊ฒ์ ๊ณ ํต์ค๋ฝ์ต๋๋ค. ์ด๊ฒ์ for-of ๋ฃจํ๊ฐ ๊ฐ์ฒด์ ์ธ๋ชจ๊ฐ ์๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๊น? ๋ฐ๋์๋ ์๋๋๋ค ...
๋ฐ๋ณต ๊ฐ๋ฅํ ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ฌด์์
๋๊น?
[Symbol.iterator]
๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ฐ๋ณต์๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
let object = {
"name":"Michal",
"surname":"Zarzycki",
*[Symbol.iterator]() {
let keys = Object.keys(object);
for(let i=0; i<keys.length; i++) {
yield [`${keys[i]}: ${object[keys[i]]}`]
}
}
}
for(const props of object) {
console.log(props)
}
//[ 'name: Michal' ]
//[ 'surname: Zarzycki' ]
์์ ์๋ฅผ ๋ณด๋ฉด ๊ด์ฐฐ์๋ ์ด๊ฒ์ด ๊ฐ์ฒด์ ํค-๊ฐ ์์ ์ธ์ํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ for ... in ๋ฃจํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๋ซ์ง ์์๊น์? ์ด๊ฒ์ ๋ ๋ค๋ฅธ ์ข์ ์ง๋ฌธ์
๋๋ค. ๋ฐ๋ณต์๋ฅผ ์์ฑํ๊ฑฐ๋ ๊ธฐ๋ณธ ๋ฐ๋ณต์๋ฅผ ๋ฎ์ด์ฐ๋ ๊ฒ์ ์ฐ๋ฆฌ์ ๋ฐ๋ณต์ด ๋ฐ๋์ ์ผ๋ฐ์ ์ผ ํ์๋ ์๋ ์ข ๋ ํน์ ํ ์ํฉ์์ ์๋ํ์ง๋ง, ๊ฐ์ฒด์ ๋ฐ๋ณต์๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ ๋ค๋ฅธ ์ด์ ๋ก ์ ์ฉํ ์ ์์ต๋๋ค. for..in์ ๊ธฐํธ๋ฅผ ๋ณผ ์ ์์ต๋๋ค:
let symbol1 = Symbol('symbol1')
obj = {
"name":"Michal",
"surname":"Zarzycki",
}
obj[symbol1] = "Secret message: I love puppies"
for(const prop in obj) {
console.log(`${key}: ${prop[key]}`)
}
//console.log
//name: Michal
//surname: Zarzycki
์ด, ๋ด ๋น๋ฐ ๋ฉ์์ง๋ ์ด์ ์์ ํฉ๋๋ค. ๋ฐ๋ณต์๋ฅผ ์ฌ์ฉํ์ง ์๋ ํ:
let symbol1 = Symbol('symbol1')
obj = {
"name":"Michal",
"surname":"Zarzycki",
*[Symbol.iterator]() {
let arr = Object.getOwnPropertySymbols(obj)
let ob_keys = Object.keys(obj);
let keys = [...arr, ...ob_keys]
for(let i=0; i<keys.length; i++) {
yield [keys[i], obj[keys[i]]]
}
}
}
obj[symbol1] = "Secret message: I love puppies"
for(const prop of obj) {
console.log(prop)
}
//console.log():
//[ Symbol(Symbol.iterator), [GeneratorFunction:[Symbol.iterator]] ]
//[ Symbol(symbol1), 'Secret message: I love puppies' ]
//[ 'name', 'Michal' ]
//[ 'surname', 'Zarzycki' ]
๋ณด์๋ค์ํผ, ๋ฐ๋ณต์๋ ๋งค์ฐ ๊ฐ๋ ฅํ ๋๊ตฌ์ด๋ฉฐ ๋ง์ ์ฉ๋๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๋๋ง์ ๋ฐ๋ณต์๋ฅผ ๋ง๋๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ฐ๋ณตํ ๋ ๋ฉ์์ง ๋น๋ฐ์ ๊ฑด๋๋ธ ์ ์์ต๋๋ค. ๐.
์ฝ์ด ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค! ๐๐๐
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐๋ฐ๋ณต์์ ์์ฑ์ 101 #1๐), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค
https://dev.to/michalpzarzycki/iterators-and-generators-101-1-3o0f
ํ
์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ
์ธ ๋ฐ๊ฒฌ์ ์ ๋
(Collection and Share based on the CC Protocol.)
//I want to list all combinations of these three arrays
let colors = ["Red ", "Blue ", "Yellow "];
let cars = ["BMW ", "Audi ", "Fiat "];
let models = ["v1.", "v2.", "v3."];
let allOptionsForLoop = [];
let allOptionsForOfLoop = [];
//Let's use for loop to create allOptionsForLoop:
for(let i=0; i<colors.length; i++) {
for(let j=0; j<cars.length; j++) {
for(let k=0; k<models.length; k++) {
allOptionsForLoop.push(colors[i]+cars[j]+models[k]);
}
}
}
// And for-of loop to create allOptionsForOfLoop;
for(const color of colors) {
for(const car of cars) {
for(const model of models) {
allOptionsForOfLoop.push(color+car+model)
}
}
}
console.log(allOptionsForLoop)
console.log("_________________________")
console.log(allOptionsForOfLoop)
console.log(JSON.stringify(allOptionsForLoop)===JSON.stringify(allOptionsForOfLoop))
// [
'Red BMW v1.', 'Red BMW v2.',
'Red BMW v3.', 'Red Audi v1.',
'Red Audi v2.', 'Red Audi v3.',
'Red Fiat v1.', 'Red Fiat v2.',
'Red Fiat v3.', 'Blue BMW v1.',
'Blue BMW v2.', 'Blue BMW v3.',
'Blue Audi v1.', 'Blue Audi v2.',
'Blue Audi v3.', 'Blue Fiat v1.',
'Blue Fiat v2.', 'Blue Fiat v3.',
'Yellow BMW v1.', 'Yellow BMW v2.',
'Yellow BMW v3.', 'Yellow Audi v1.',
'Yellow Audi v2.', 'Yellow Audi v3.',
'Yellow Fiat v1.', 'Yellow Fiat v2.',
'Yellow Fiat v3.'
]
_________________________
[
'Red BMW v1.', 'Red BMW v2.',
'Red BMW v3.', 'Red Audi v1.',
'Red Audi v2.', 'Red Audi v3.',
'Red Fiat v1.', 'Red Fiat v2.',
'Red Fiat v3.', 'Blue BMW v1.',
'Blue BMW v2.', 'Blue BMW v3.',
'Blue Audi v1.', 'Blue Audi v2.',
'Blue Audi v3.', 'Blue Fiat v1.',
'Blue Fiat v2.', 'Blue Fiat v3.',
'Yellow BMW v1.', 'Yellow BMW v2.',
'Yellow BMW v3.', 'Yellow Audi v1.',
'Yellow Audi v2.', 'Yellow Audi v3.',
'Yellow Fiat v1.', 'Yellow Fiat v2.',
'Yellow Fiat v3.'
]
true
for-of ๋ฃจํ์ ์๋ ๋ฐฉ์์ ์์ ํ ์ดํดํ๊ธฐ ์ ์ ๋ฐ๋ณต์๋ฅผ ์ดํดํด์ผ ํฉ๋๋ค. ๋ฐ๋ณต์๋ ๋ฌด์์ ๋๊น?
๋ฐ๋ณต์๋ ๋ฐ๋ณตํ๋๋ก ์ค๊ณ๋ ๋ค์ ํน์ดํ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง ๊ฐ์ฒด์ ๋๋ค. ๋ฐ๋ณต์๋ ์ปฌ๋ ์ ์์ ์์น๋ฅผ ์ถ์ ํ๋ ๋ด๋ถ ํฌ์ธํฐ์ ๊ฒฐ๊ณผ ๊ฐ์ฒด๋ฅผ ํฌํจํ๋
next()
๋ฉ์๋๋ฅผ ํฌํจํฉ๋๋ค. ๊ฒฐ๊ณผ ๊ฐ์ฒด์๋ ๋ ๊ฐ์ ๊ฐ{value, done}
์ด ์๊ณ , value์๋ ๋ฐ๋ณต์์ ๋ฐํ ๊ฐ์ด ํฌํจ๋๋ฉฐ, done์ ์ฃผ์ด์ง ๊ฐ์ด ๋ง์ง๋ง์ผ๋ก ๋ฐํ๋ ๊ฐ์ธ์งtrue
์๋์งfalse
์๋ ค์ค๋๋ค.์ด ์ ๋ณด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ด๋ฌํ ๋ฐ๋ณต์๋ฅผ ์ง์ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
function myFirstIterator(itemsToIterate) {
// i is an "iteration pointer"
let i = 0;
return {
next: function() {
//check if itemsToIterate[i] exists
let done = i >= itemsToIterate.length;
//if its done return undefined
let value = !done ? itemsToIterate[i] : undefined;
//ok we've got {done, value} so lets move forward
i++;
return {
done,
value
}
}
}
}
let iterateMe = myFirstIterator(["Hello", "World", "!"]);
console.log("1. ", iterateMe.next()) // 1. { done: false, value: 'Hello' }
console.log("2. ", iterateMe.next()) // 2. { done: false, value: 'World' }
console.log("3. ", iterateMe.next()) // 3. { done: false, value: '!' }
console.log("4. ", iterateMe.next()) // 4. { done: true, value: undefined }
console.log("5. ", iterateMe.next()) // 5. { done: true, value: undefined }
๋ณด์๋ค์ํผ ์์ ์ค๋ช ๋ ๊ท์น(ES6์ ์ ์๋ ๊ท์น)์ ๋ฐ๋ผ ๋์ํ๋ ๋ฐ๋ณต์๋ฅผ ๋ง๋๋ ๊ฒ์ ์ฌ์ด ์ผ์ด ์๋๋๋ค. ๋คํํ๋ ES6์ด ๊ตฌ์ถ๋์ด ๋ฐ๋ณต์ ์์ฑ์ ๋ ์ฝ๊ฒ ํด์ฃผ๋ ์์ฑ๊ธฐ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด๋ป๊ฒ?
๋ฐ์ ๊ธฐ
๊ฐ๋จํ ๋งํด์ ์ ๋๋ ์ดํฐ๋ ๋ฐ๋ณต์๋ฅผ ๋ฐํํ๋ ํจ์์
๋๋ค. ์๋ ์ฝ๋๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
// * placed in front of myFisrstGenerator makes this function a generator
function *myFirstGenerator() {
//yield specifies the values that should be returned by the iterator when calling the next () method
yield "Hello";
yield "World";
yield "!"
}
let iterateMe = myFirstGenerator()
console.log("1. ", iterateMe.next()) // 1. { done: false, value: 'Hello' }
console.log("2. ", iterateMe.next()) // 2. { done: false, value: 'World' }
console.log("3. ", iterateMe.next()) // 3. { done: false, value: '!' }
console.log("4. ", iterateMe.next()) // 4. { done: true, value: undefined }
console.log("5. ", iterateMe.next()) // 5. { done: true, value: undefined }
๊ฐ yield ๋ช
๋ น ํ์ ์์ฑ๊ธฐ๋ ์์ฑ๊ธฐ ํจ์ ์คํ์ ์ค์งํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ฐ๋ณต์์ ์์๋ฅผ ์ถ๊ฐํ๋ ์์ฑ๊ธฐ๋ฅผ ๊ฐ๋ฐํ ์ ์์ต๋๋ค.
function *iterateMyArray(myArray) {
for(let i=0; i<myArray.length; i++) {
yield myArray[i]
}
}
let iterateMe = iterateMyArray(["Hello", "World", "!"])
console.log("1. ", iterateMe.next()) // 1. { done: false, value: 'Hello' }
console.log("2. ", iterateMe.next()) // 2. { done: false, value: 'World' }
console.log("3. ", iterateMe.next()) // 3. { done: false, value: '!' }
console.log("4. ", iterateMe.next()) // 4. { done: true, value: undefined }
console.log("5. ", iterateMe.next()) // 5. { done: true, value: undefined }
์ด์ ์์ฑ๊ธฐ* iterateMyArray()
๋ฅผ ์ฒ์๋ถํฐ ๋ฐ๋ณต์์ ๋น๊ตํฉ๋๋ค. ES5์ ๋น๊ตํ์ฌ ์ ๋๋ ์ดํฐ๋ก ES6 ๋ฐ๋ณต์๋ฅผ ์์ฑํ๋ ์ฉ์ด์ฑ์ ์ฐจ์ด๋ ์์ฒญ๋ฉ๋๋ค.
์ ๋๋ ์ดํฐ ํ๊ณผ ํธ๋ฆญ
์์ฑ๊ธฐ ๋ง๋ค๊ธฐ:
//โ
โ
โ
function* sampleGenerator() {}
//โ
โ
โ
function * sampleGenerator() {}
//โ
โ
โ
function *sampleGenerator() {}
//โ
โ
โ
function*sampleGenerator() {}
//โ
โ
โ
let sampleGenerator = function *() {}
//โ โ โ
let sampleGenerator = *() => {}
yield๋ฅผ ์ฌ์ฉํ ๋ ์ฃผ์ํ์ธ์.
//yield can be used only inside generators
//โ โ โ
function *newGen() {
function insideNewGen() {
//it will throw an error
yield "Hello"
}
}
์์ฑ๊ธฐ๋ฅผ ๊ฐ์ฒด ๋ฉ์๋๋ก ์ถ๊ฐํ ์ ์์ต๋๋ค.
let obj = {
//like this (ES5)โ
โ
โ
:
generatorNr1: function*(myArray) {
for(let i=0; i<myArray.length; i++) {
yield myArray[i]
}
},
//or like this (ES6)โ
โ
โ
:
*generatorNr2(myArray) {
for(let i=0; i<myArray.length; i++) {
yield myArray[i]
}
}
}
[Symbol.iterator]
ํ์ง๋ง for ๋ฃจํ๋ ์ด๋ป์ต๋๊น? ๋ฐ๋ณต์์ ์์ฑ๊ธฐ์ ๋ํ ์ฝ๋๊ฐ ๋๋ฌด ๋ง์ง๋ง for ๋ฃจํ์ ์ด๋ค ๊ด๋ จ์ด ์์ต๋๊น? ์ข์ ์ง๋ฌธ. ๋ฐ๋ณต์๋ ๋ฐ๋ณตํ๋ ์์, ์ฆ Symbol.iterator ๊ฐ์ฒด์ ์ฐ๊ฒฐ๋ฉ๋๋ค. ์ฃผ์ด์ง ๊ฐ์ฒด์ ๋ํ ๋ฐ๋ณต์๋ฅผ ๋ฐํํ๋ ํจ์๋ฅผ ์ง์ ํฉ๋๋ค. ๋ชจ๋ ๋ฐ๋ณต ๊ฐ๋ฅํ ์์์๋ ๊ธฐ๋ณธ Symbol.iterator๊ฐ ์ ์๋์ด ์์ต๋๋ค. ์ด ๋๋ถ์ for ๋ฃจํ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ฃจํ๊ฐ ๋ฐ๋ณต์ ๋ํ ์ง์์ ํ์๋ก ํ๋ ๋ฐ๋ณต์์ด๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ทธ๋ฌ๋ ๋ชจ๋ ์์์ ๊ทธ๋ฌํ ๊ธฐ๋ณธ ๋ฐ๋ณต์๊ฐ ์์ต๋๊น? ์ ๊ฒ ํด๋ณด์:
function doIhaveDefaultIterator(obj) {
return typeof obj[Symbol.iterator] === 'function'
}
//arrayโ
console.log(doIhaveDefaultIterator(["Hello", "World", "1"])) //true
//Mapโ
console.log(doIhaveDefaultIterator(new Map())) //true
//Stringโ
console.log(doIhaveDefaultIterator("hello")) //true
//Objectโ
console.log(doIhaveDefaultIterator(new Object())) //false
console.log(doIhaveDefaultIterator({})) //false
//Setโ
console.log(doIhaveDefaultIterator(new Set())) //true
//Weakmapโ
console.log(doIhaveDefaultIterator(new WeakMap)) //false
//WeakSetโ
console.log(doIhaveDefaultIterator(new WeakSet)) //false
์ฐ์. ๋ณด์๋ค์ํผ JS์ ๋ชจ๋ ๊ฒ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐ๋ณต๋ ์ ์๋ ๊ฒ์ ์๋๋๋ค. ํนํ ๊ฐ์ฒด์ ๋ฐ๋ณต์๊ฐ ์๋ ๊ฒ์ ๊ณ ํต์ค๋ฝ์ต๋๋ค. ์ด๊ฒ์ for-of ๋ฃจํ๊ฐ ๊ฐ์ฒด์ ์ธ๋ชจ๊ฐ ์๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๊น? ๋ฐ๋์๋ ์๋๋๋ค ...
๋ฐ๋ณต ๊ฐ๋ฅํ ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ฌด์์
๋๊น?
[Symbol.iterator]
๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ฐ๋ณต์๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
let object = {
"name":"Michal",
"surname":"Zarzycki",
*[Symbol.iterator]() {
let keys = Object.keys(object);
for(let i=0; i<keys.length; i++) {
yield [`${keys[i]}: ${object[keys[i]]}`]
}
}
}
for(const props of object) {
console.log(props)
}
//[ 'name: Michal' ]
//[ 'surname: Zarzycki' ]
์์ ์๋ฅผ ๋ณด๋ฉด ๊ด์ฐฐ์๋ ์ด๊ฒ์ด ๊ฐ์ฒด์ ํค-๊ฐ ์์ ์ธ์ํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ for ... in ๋ฃจํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๋ซ์ง ์์๊น์? ์ด๊ฒ์ ๋ ๋ค๋ฅธ ์ข์ ์ง๋ฌธ์
๋๋ค. ๋ฐ๋ณต์๋ฅผ ์์ฑํ๊ฑฐ๋ ๊ธฐ๋ณธ ๋ฐ๋ณต์๋ฅผ ๋ฎ์ด์ฐ๋ ๊ฒ์ ์ฐ๋ฆฌ์ ๋ฐ๋ณต์ด ๋ฐ๋์ ์ผ๋ฐ์ ์ผ ํ์๋ ์๋ ์ข ๋ ํน์ ํ ์ํฉ์์ ์๋ํ์ง๋ง, ๊ฐ์ฒด์ ๋ฐ๋ณต์๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ ๋ค๋ฅธ ์ด์ ๋ก ์ ์ฉํ ์ ์์ต๋๋ค. for..in์ ๊ธฐํธ๋ฅผ ๋ณผ ์ ์์ต๋๋ค:
let symbol1 = Symbol('symbol1')
obj = {
"name":"Michal",
"surname":"Zarzycki",
}
obj[symbol1] = "Secret message: I love puppies"
for(const prop in obj) {
console.log(`${key}: ${prop[key]}`)
}
//console.log
//name: Michal
//surname: Zarzycki
์ด, ๋ด ๋น๋ฐ ๋ฉ์์ง๋ ์ด์ ์์ ํฉ๋๋ค. ๋ฐ๋ณต์๋ฅผ ์ฌ์ฉํ์ง ์๋ ํ:
let symbol1 = Symbol('symbol1')
obj = {
"name":"Michal",
"surname":"Zarzycki",
*[Symbol.iterator]() {
let arr = Object.getOwnPropertySymbols(obj)
let ob_keys = Object.keys(obj);
let keys = [...arr, ...ob_keys]
for(let i=0; i<keys.length; i++) {
yield [keys[i], obj[keys[i]]]
}
}
}
obj[symbol1] = "Secret message: I love puppies"
for(const prop of obj) {
console.log(prop)
}
//console.log():
//[ Symbol(Symbol.iterator), [GeneratorFunction:[Symbol.iterator]] ]
//[ Symbol(symbol1), 'Secret message: I love puppies' ]
//[ 'name', 'Michal' ]
//[ 'surname', 'Zarzycki' ]
๋ณด์๋ค์ํผ, ๋ฐ๋ณต์๋ ๋งค์ฐ ๊ฐ๋ ฅํ ๋๊ตฌ์ด๋ฉฐ ๋ง์ ์ฉ๋๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๋๋ง์ ๋ฐ๋ณต์๋ฅผ ๋ง๋๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ฐ๋ณตํ ๋ ๋ฉ์์ง ๋น๋ฐ์ ๊ฑด๋๋ธ ์ ์์ต๋๋ค. ๐.
์ฝ์ด ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค! ๐๐๐
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐๋ฐ๋ณต์์ ์์ฑ์ 101 #1๐), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค
https://dev.to/michalpzarzycki/iterators-and-generators-101-1-3o0f
ํ
์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ
์ธ ๋ฐ๊ฒฌ์ ์ ๋
(Collection and Share based on the CC Protocol.)
// * placed in front of myFisrstGenerator makes this function a generator
function *myFirstGenerator() {
//yield specifies the values that should be returned by the iterator when calling the next () method
yield "Hello";
yield "World";
yield "!"
}
let iterateMe = myFirstGenerator()
console.log("1. ", iterateMe.next()) // 1. { done: false, value: 'Hello' }
console.log("2. ", iterateMe.next()) // 2. { done: false, value: 'World' }
console.log("3. ", iterateMe.next()) // 3. { done: false, value: '!' }
console.log("4. ", iterateMe.next()) // 4. { done: true, value: undefined }
console.log("5. ", iterateMe.next()) // 5. { done: true, value: undefined }
function *iterateMyArray(myArray) {
for(let i=0; i<myArray.length; i++) {
yield myArray[i]
}
}
let iterateMe = iterateMyArray(["Hello", "World", "!"])
console.log("1. ", iterateMe.next()) // 1. { done: false, value: 'Hello' }
console.log("2. ", iterateMe.next()) // 2. { done: false, value: 'World' }
console.log("3. ", iterateMe.next()) // 3. { done: false, value: '!' }
console.log("4. ", iterateMe.next()) // 4. { done: true, value: undefined }
console.log("5. ", iterateMe.next()) // 5. { done: true, value: undefined }
์์ฑ๊ธฐ ๋ง๋ค๊ธฐ:
//โ
โ
โ
function* sampleGenerator() {}
//โ
โ
โ
function * sampleGenerator() {}
//โ
โ
โ
function *sampleGenerator() {}
//โ
โ
โ
function*sampleGenerator() {}
//โ
โ
โ
let sampleGenerator = function *() {}
//โ โ โ
let sampleGenerator = *() => {}
yield๋ฅผ ์ฌ์ฉํ ๋ ์ฃผ์ํ์ธ์.
//yield can be used only inside generators
//โ โ โ
function *newGen() {
function insideNewGen() {
//it will throw an error
yield "Hello"
}
}
์์ฑ๊ธฐ๋ฅผ ๊ฐ์ฒด ๋ฉ์๋๋ก ์ถ๊ฐํ ์ ์์ต๋๋ค.
let obj = {
//like this (ES5)โ
โ
โ
:
generatorNr1: function*(myArray) {
for(let i=0; i<myArray.length; i++) {
yield myArray[i]
}
},
//or like this (ES6)โ
โ
โ
:
*generatorNr2(myArray) {
for(let i=0; i<myArray.length; i++) {
yield myArray[i]
}
}
}
[Symbol.iterator]
ํ์ง๋ง for ๋ฃจํ๋ ์ด๋ป์ต๋๊น? ๋ฐ๋ณต์์ ์์ฑ๊ธฐ์ ๋ํ ์ฝ๋๊ฐ ๋๋ฌด ๋ง์ง๋ง for ๋ฃจํ์ ์ด๋ค ๊ด๋ จ์ด ์์ต๋๊น? ์ข์ ์ง๋ฌธ. ๋ฐ๋ณต์๋ ๋ฐ๋ณตํ๋ ์์, ์ฆ Symbol.iterator ๊ฐ์ฒด์ ์ฐ๊ฒฐ๋ฉ๋๋ค. ์ฃผ์ด์ง ๊ฐ์ฒด์ ๋ํ ๋ฐ๋ณต์๋ฅผ ๋ฐํํ๋ ํจ์๋ฅผ ์ง์ ํฉ๋๋ค. ๋ชจ๋ ๋ฐ๋ณต ๊ฐ๋ฅํ ์์์๋ ๊ธฐ๋ณธ Symbol.iterator๊ฐ ์ ์๋์ด ์์ต๋๋ค. ์ด ๋๋ถ์ for ๋ฃจํ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ฃจํ๊ฐ ๋ฐ๋ณต์ ๋ํ ์ง์์ ํ์๋ก ํ๋ ๋ฐ๋ณต์์ด๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ทธ๋ฌ๋ ๋ชจ๋ ์์์ ๊ทธ๋ฌํ ๊ธฐ๋ณธ ๋ฐ๋ณต์๊ฐ ์์ต๋๊น? ์ ๊ฒ ํด๋ณด์:
function doIhaveDefaultIterator(obj) {
return typeof obj[Symbol.iterator] === 'function'
}
//arrayโ
console.log(doIhaveDefaultIterator(["Hello", "World", "1"])) //true
//Mapโ
console.log(doIhaveDefaultIterator(new Map())) //true
//Stringโ
console.log(doIhaveDefaultIterator("hello")) //true
//Objectโ
console.log(doIhaveDefaultIterator(new Object())) //false
console.log(doIhaveDefaultIterator({})) //false
//Setโ
console.log(doIhaveDefaultIterator(new Set())) //true
//Weakmapโ
console.log(doIhaveDefaultIterator(new WeakMap)) //false
//WeakSetโ
console.log(doIhaveDefaultIterator(new WeakSet)) //false
์ฐ์. ๋ณด์๋ค์ํผ JS์ ๋ชจ๋ ๊ฒ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐ๋ณต๋ ์ ์๋ ๊ฒ์ ์๋๋๋ค. ํนํ ๊ฐ์ฒด์ ๋ฐ๋ณต์๊ฐ ์๋ ๊ฒ์ ๊ณ ํต์ค๋ฝ์ต๋๋ค. ์ด๊ฒ์ for-of ๋ฃจํ๊ฐ ๊ฐ์ฒด์ ์ธ๋ชจ๊ฐ ์๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๊น? ๋ฐ๋์๋ ์๋๋๋ค ...
๋ฐ๋ณต ๊ฐ๋ฅํ ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ฌด์์
๋๊น?
[Symbol.iterator]
๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ฐ๋ณต์๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
let object = {
"name":"Michal",
"surname":"Zarzycki",
*[Symbol.iterator]() {
let keys = Object.keys(object);
for(let i=0; i<keys.length; i++) {
yield [`${keys[i]}: ${object[keys[i]]}`]
}
}
}
for(const props of object) {
console.log(props)
}
//[ 'name: Michal' ]
//[ 'surname: Zarzycki' ]
์์ ์๋ฅผ ๋ณด๋ฉด ๊ด์ฐฐ์๋ ์ด๊ฒ์ด ๊ฐ์ฒด์ ํค-๊ฐ ์์ ์ธ์ํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ for ... in ๋ฃจํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๋ซ์ง ์์๊น์? ์ด๊ฒ์ ๋ ๋ค๋ฅธ ์ข์ ์ง๋ฌธ์
๋๋ค. ๋ฐ๋ณต์๋ฅผ ์์ฑํ๊ฑฐ๋ ๊ธฐ๋ณธ ๋ฐ๋ณต์๋ฅผ ๋ฎ์ด์ฐ๋ ๊ฒ์ ์ฐ๋ฆฌ์ ๋ฐ๋ณต์ด ๋ฐ๋์ ์ผ๋ฐ์ ์ผ ํ์๋ ์๋ ์ข ๋ ํน์ ํ ์ํฉ์์ ์๋ํ์ง๋ง, ๊ฐ์ฒด์ ๋ฐ๋ณต์๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ ๋ค๋ฅธ ์ด์ ๋ก ์ ์ฉํ ์ ์์ต๋๋ค. for..in์ ๊ธฐํธ๋ฅผ ๋ณผ ์ ์์ต๋๋ค:
let symbol1 = Symbol('symbol1')
obj = {
"name":"Michal",
"surname":"Zarzycki",
}
obj[symbol1] = "Secret message: I love puppies"
for(const prop in obj) {
console.log(`${key}: ${prop[key]}`)
}
//console.log
//name: Michal
//surname: Zarzycki
์ด, ๋ด ๋น๋ฐ ๋ฉ์์ง๋ ์ด์ ์์ ํฉ๋๋ค. ๋ฐ๋ณต์๋ฅผ ์ฌ์ฉํ์ง ์๋ ํ:
let symbol1 = Symbol('symbol1')
obj = {
"name":"Michal",
"surname":"Zarzycki",
*[Symbol.iterator]() {
let arr = Object.getOwnPropertySymbols(obj)
let ob_keys = Object.keys(obj);
let keys = [...arr, ...ob_keys]
for(let i=0; i<keys.length; i++) {
yield [keys[i], obj[keys[i]]]
}
}
}
obj[symbol1] = "Secret message: I love puppies"
for(const prop of obj) {
console.log(prop)
}
//console.log():
//[ Symbol(Symbol.iterator), [GeneratorFunction:[Symbol.iterator]] ]
//[ Symbol(symbol1), 'Secret message: I love puppies' ]
//[ 'name', 'Michal' ]
//[ 'surname', 'Zarzycki' ]
๋ณด์๋ค์ํผ, ๋ฐ๋ณต์๋ ๋งค์ฐ ๊ฐ๋ ฅํ ๋๊ตฌ์ด๋ฉฐ ๋ง์ ์ฉ๋๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๋๋ง์ ๋ฐ๋ณต์๋ฅผ ๋ง๋๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ฐ๋ณตํ ๋ ๋ฉ์์ง ๋น๋ฐ์ ๊ฑด๋๋ธ ์ ์์ต๋๋ค. ๐.
์ฝ์ด ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค! ๐๐๐
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐๋ฐ๋ณต์์ ์์ฑ์ 101 #1๐), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค
https://dev.to/michalpzarzycki/iterators-and-generators-101-1-3o0f
ํ
์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ
์ธ ๋ฐ๊ฒฌ์ ์ ๋
(Collection and Share based on the CC Protocol.)
function doIhaveDefaultIterator(obj) {
return typeof obj[Symbol.iterator] === 'function'
}
//arrayโ
console.log(doIhaveDefaultIterator(["Hello", "World", "1"])) //true
//Mapโ
console.log(doIhaveDefaultIterator(new Map())) //true
//Stringโ
console.log(doIhaveDefaultIterator("hello")) //true
//Objectโ
console.log(doIhaveDefaultIterator(new Object())) //false
console.log(doIhaveDefaultIterator({})) //false
//Setโ
console.log(doIhaveDefaultIterator(new Set())) //true
//Weakmapโ
console.log(doIhaveDefaultIterator(new WeakMap)) //false
//WeakSetโ
console.log(doIhaveDefaultIterator(new WeakSet)) //false
[Symbol.iterator]
๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ฐ๋ณต์๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.let object = {
"name":"Michal",
"surname":"Zarzycki",
*[Symbol.iterator]() {
let keys = Object.keys(object);
for(let i=0; i<keys.length; i++) {
yield [`${keys[i]}: ${object[keys[i]]}`]
}
}
}
for(const props of object) {
console.log(props)
}
//[ 'name: Michal' ]
//[ 'surname: Zarzycki' ]
์์ ์๋ฅผ ๋ณด๋ฉด ๊ด์ฐฐ์๋ ์ด๊ฒ์ด ๊ฐ์ฒด์ ํค-๊ฐ ์์ ์ธ์ํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ for ... in ๋ฃจํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๋ซ์ง ์์๊น์? ์ด๊ฒ์ ๋ ๋ค๋ฅธ ์ข์ ์ง๋ฌธ์ ๋๋ค. ๋ฐ๋ณต์๋ฅผ ์์ฑํ๊ฑฐ๋ ๊ธฐ๋ณธ ๋ฐ๋ณต์๋ฅผ ๋ฎ์ด์ฐ๋ ๊ฒ์ ์ฐ๋ฆฌ์ ๋ฐ๋ณต์ด ๋ฐ๋์ ์ผ๋ฐ์ ์ผ ํ์๋ ์๋ ์ข ๋ ํน์ ํ ์ํฉ์์ ์๋ํ์ง๋ง, ๊ฐ์ฒด์ ๋ฐ๋ณต์๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ ๋ค๋ฅธ ์ด์ ๋ก ์ ์ฉํ ์ ์์ต๋๋ค. for..in์ ๊ธฐํธ๋ฅผ ๋ณผ ์ ์์ต๋๋ค:
let symbol1 = Symbol('symbol1')
obj = {
"name":"Michal",
"surname":"Zarzycki",
}
obj[symbol1] = "Secret message: I love puppies"
for(const prop in obj) {
console.log(`${key}: ${prop[key]}`)
}
//console.log
//name: Michal
//surname: Zarzycki
์ด, ๋ด ๋น๋ฐ ๋ฉ์์ง๋ ์ด์ ์์ ํฉ๋๋ค. ๋ฐ๋ณต์๋ฅผ ์ฌ์ฉํ์ง ์๋ ํ:
let symbol1 = Symbol('symbol1')
obj = {
"name":"Michal",
"surname":"Zarzycki",
*[Symbol.iterator]() {
let arr = Object.getOwnPropertySymbols(obj)
let ob_keys = Object.keys(obj);
let keys = [...arr, ...ob_keys]
for(let i=0; i<keys.length; i++) {
yield [keys[i], obj[keys[i]]]
}
}
}
obj[symbol1] = "Secret message: I love puppies"
for(const prop of obj) {
console.log(prop)
}
//console.log():
//[ Symbol(Symbol.iterator), [GeneratorFunction:[Symbol.iterator]] ]
//[ Symbol(symbol1), 'Secret message: I love puppies' ]
//[ 'name', 'Michal' ]
//[ 'surname', 'Zarzycki' ]
๋ณด์๋ค์ํผ, ๋ฐ๋ณต์๋ ๋งค์ฐ ๊ฐ๋ ฅํ ๋๊ตฌ์ด๋ฉฐ ๋ง์ ์ฉ๋๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๋๋ง์ ๋ฐ๋ณต์๋ฅผ ๋ง๋๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ฐ๋ณตํ ๋ ๋ฉ์์ง ๋น๋ฐ์ ๊ฑด๋๋ธ ์ ์์ต๋๋ค. ๐.
์ฝ์ด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค! ๐๐๐
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐๋ฐ๋ณต์์ ์์ฑ์ 101 #1๐), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://dev.to/michalpzarzycki/iterators-and-generators-101-1-3o0fํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค