๐Ÿš€๋ฐ˜๋ณต์ž์™€ ์ƒ์„ฑ์ž 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' ]



๋ณด์‹œ๋‹ค์‹œํ”ผ, ๋ฐ˜๋ณต์ž๋Š” ๋งค์šฐ ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ด๋ฉฐ ๋งŽ์€ ์šฉ๋„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋งŒ์˜ ๋ฐ˜๋ณต์ž๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ณตํ•  ๋•Œ ๋ฉ”์‹œ์ง€ ๋น„๋ฐ€์„ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜ƒ.

์ฝ์–ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๐Ÿš€๐Ÿš€๐Ÿš€

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ