ES6์์ ๋์ ๋ ์ดํฐ๋ ์ด์ ํ๋กํ ์ฝ์ ์ํ ๊ฐ๋ฅํ ๋ฐ์ดํฐ ์ปฌ๋ ์ ์ ๋ง๋ค๊ธฐ ์ํด ECMAScript ์ฌ์์ ์ ์ํ์ฌ ๋ฏธ๋ฆฌ ์ฝ์ํ ๊ท์น์ด๋ค.
์ดํฐ๋ฌ๋ธ ํ๋กํ ์ฝ์ ์ค์ํ ๊ฐ์ฒด๋ฅผ ์ดํฐ๋ฌ๋ธ์ด๋ผ ํ๋ค. ์ดํฐ๋ฌ๋ธ์ Symbol.iterator๋ฅผ ํ๋กํผํฐ ํค๋ก ์ฌ์ฉํ ๋ฉ์๋๋ฅผ ์ง์ ๊ตฌํํ๊ฑฐ๋ ํ๋กํ ํ์ ์ฒด์ธ์ ํตํด ์์๋ฐ์ ๊ฐ์ฒด๋ฅผ ๋งํ๋ค.
์ดํฐ๋ฌ๋ธ์ธ์ง ํ์ธํ๋ ํจ์๋ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํ
const isIterable = v => v !== null && typeof v[Symbol.iterator] === 'function';
// ๋ฐฐ์ด, ๋ฌธ์์ด, Map, Set ๋ฑ์ ์ดํฐ๋ฌ๋ธ์ด๋ค.
isIterable([]); // true
isIterable(''); // true
isIterable(new Map()); // true
isIterable(new Set()); // true
isIterable(new Set()); // true
isIterable({}); // false
์ดํฐ๋ฌ๋ธ์ Symbol.iterator ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์ดํฐ๋ ์ดํฐ ํ๋กํ ์ฝ์ ์ค์ํ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐํํ๋ค. ์ดํฐ๋ฌ๋ธ์ Symbol.iterator ๋ฉ์๋๊ฐ ๋ฐํํ ์ดํฐ๋ ์ดํฐ๋ next ๋ฉ์๋๋ฅผ ๊ฐ๋๋ค.
// ๋ฐฐ์ด์ ์ดํฐ๋ฌ๋ธ ํ๋กํ ์ฝ์ ์ค์ํ ์ดํฐ๋ฌ๋ธ์ด๋ค.
const array = [1,2,3];
// Symbol.iterator ๋ฉ์๋๋ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐํํ๋ค.
const iterator = array[Symbol.iterator]();
// Symbol.iterator ๋ฉ์๋๊ฐ ๋ดํํ ์ดํฐ๋ ์ดํฐ๋ next ๋ฉ์๋๋ฅผ ๊ฐ๋๋ค.
console.log('next' in iterator); // true
์ดํฐ๋ ์ดํฐ์ next ๋ฉ์๋๋ ์ดํฐ๋ฌ๋ธ์ ๊ฐ ์์๋ฅผ ์ํํ๊ธฐ ์ํ ํฌ์ธํฐ์ ์ญํ ์ ํ๋ค. ์ฆ next ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์ดํฐ๋ฌ๋ธ์ ์์ฐจ์ ์ผ๋ก ํ ๋จ๊ฒ์ฉ ์ํํ๋ฉฐ ์ํ ๊ฒฐ๊ณผ๋ฅผ ๋ํ๋ด๋ ์ดํฐ๋ ์ดํฐ ๋ฆฌ์ ํธ ๊ฐ์ฒด๋ฅผ ๋ฐํ
์ดํฐ๋ ์ดํฐ์ next ๋ฉ์๋๊ฐ ๋ฐํํ๋ ์ดํฐ๋ ์ดํฐ ๋ฆฌ์ ํธ ๊ฐ์ฒด์ value ํ๋กํผํฐ๋ ํ์ฌ ์ํ ์ค์ธ ์ดํฐ๋ฌ๋ธ์ ๊ฐ์ ๋ํ๋ด๋ฉฐ done ํ๋กํผํฐ๋ ์ดํฐ๋ฌ๋ธ์ ์ํ ์๋ฃ ์ฌ๋ถ๋ฅผ ๋ํ๋ธ๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๋ ์ดํฐ๋ ์ด์ ํ๋กํ ์ฝ์ ์ค์ํ ๊ฐ์ฒด์ธ ๋นํธ์ธ ์ดํฐ๋ฌ๋ธ์ ์ ๊ณตํ๋ค. ๋ค์์ ํ์ค ๋นํธ์ธ ๊ฐ์ฒด๋ค์ ๋นํธ์ธ ์ดํฐ๋ฌ๋ธ์ด๋ค.
for.. of ๋ฌธ์ ์ดํฐ๋ฌ๋ธ์ ์ํํ๋ฉด์ ์ดํฐ๋ฌ๋ธ์ ์์๋ฅผ ๋ณ์์ ํ ๋นํ๋ค.
for (๋ณ์์ ์ธ๋ฌธ of ์ดํฐ๋ฌ๋ธ) {...}
for...of ๋ฌธ์ for..in ๋ฌธ์ ํ์๊ณผ ๋งค์ฐ ์ ์ฌ
for (๋ณ์์ ์ธ๋ฌธ in ๊ฐ์ฒด) {...}
for... in๋ฌธ์ ๊ฐ์ฒด์ ํ๋กํ ํ์
์ฒด์ธ ์์ ์กด์ฌํ๋ ๋ชจ๋ ํ๋กํ ํ์
์ ํ๋กํผํฐ ์ค์์ ํ๋กํผํฐ ์ดํธ๋ฆฌ๋ทฐํธ [[Enumerable]]์ ๊ฐ์ด true์ธ ํ๋กํผํฐ๋ฅผ ์ํํ๋ฉฐ ์ด๊ฑฐํ๋ค.
์ด๋ ํ๋กํผํฐ ํค๊ฐ ์ฌ๋ฒ์ธ ํ๋กํผํฐ๋ ์ด๊ฑฐํ์ง ์๋๋ค.
for...of ๋ฌธ์ ๋ด๋ถ์ ์ผ๋ก ์ดํฐ๋ ์ดํฐ์ next ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ดํฐ๋ฌ๋ธ์ ์ํํ๋ฉฐ next ๋ฉ์๋๊ฐ ๋ฐํํ ์ดํฐ๋ ์ดํฐ ๋ฆฌ์ ํธ ๊ฐ์ฒด์ value ํ๋กํผํฐ ๊ฐ์ for...of ๋ฌธ์ ๋ณ์์ ํ ๋น
.๊ทธ๋ฆฌ๊ณ ์ดํฐ๋ ์ดํฐ ๋ฆฌ์ ํธ ๊ฐ์ฒด์ done ํ๋กํผํฐ ๊ฐ์ด false ์ด๋ฉด ์ดํฐ๋ฌ๋ธ์ ์ํ๋ฅผ ๊ณ์ํ๊ณ true์ด๋ฉด ์ดํฐ๋ฌ๋ธ์ ์ํ๋ฅผ ์ค๋จํ๋ค.
for (const item of [1, 2, 3]) {
// item ๋ณ์์ ์์ฐจ์ ์ผ๋ก 1, 2, 3์ด ํ ๋น๋๋ค.
console.log(item); // 1 2 3
}
์ ์ฌ ๋ฐฐ์ด ๊ฐ์ฒด๋ ๋ง์น ๋ฐฐ์ด์ฒ๋ผ ์ธ๋ฑ์ค๋ก ํ๋กํผํฐ ๊ฐ์ ์ ๊ทผํ ์ ์๊ณ length ํ๋กํผํฐ๋ฅผ ๊ฐ๋ ๊ฐ์ฒด๋ฅผ ๋งํ๋ค.
์ ์ฌ ๋ฐฐ์ด ๊ฐ์ฒด๋length ํ๋กํผํฐ๋ฅผ ๊ฐ๊ธฐ ๋๋ฌธ์ for ๋ฌธ์ผ๋ก ์ํํ ์ ์๊ณ ,
์ธ๋ฑ์ค๋ฅผ ๋ํ๋ด๋ ์ซ์ ํ์์ ๋ฌธ์์ด์ ํ๋กํผํฐ ํค๋ก, ๊ฐ์ง๋ฏ๋ก ๋ง์น ๋ฐฐ์ด์ฒ๋ผ ์ธ๋ฑ์ค๋กํ๋กํผํฐ ๊ฐ์ ์ ๊ทผ
ํ ์ ์๋ค.
์ ์ฌ ๋ฐฐ์ด ๊ฐ์ฒด๋ ์ดํฐ๋ฌ๋ธ์ด ์๋ ์ผ๋ฐ ๊ฐ์ฒด๋ค.
๋ฐ๋ผ์ ์ ์ฌ ๋ฐฐ์ด ๊ฐ์ฒด์๋ Symbol.iterator ๋ฉ์๋๊ฐ ์๊ธฐ ๋๋ฌธ์ for...of ๋ฌธ์ผ๋ก ์ํํ ์ ์๋ค.
ES6์์ ์ดํฐ๋ฌ๋ธ์ด ๋์
๋๋ฉด์ ์ ์ฌ ๋ฐฐ์ด ๊ฐ์ฒด์ธ arguments, NodeList, HTMLCollection ๊ฐ์ฒด์ Symbol.iterator ๋ฉ์๋๋ฅผ ๊ตฌํํ์ฌ ์ดํฐ๋ฌ๋ธ์ด ๋์๋ค. ํ์ง๋ง ์ดํฐ๋ฌ๋ธ์ด ๋ ์ดํ์๋ length ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๋ฉฐ ์ธ๋ฑ์ค๋ก ์ ๊ทผํ ์ ์๋ ๊ฒ์๋ ๋ณํจ์ด ์์ผ๋ฏ๋ก ์ ์ฌ ๋ฐฐ์ด ๊ฐ์ฒด์ด๋ฉด์ ์ดํฐ๋ฌ๋ธ
์ธ ๊ฒ์ด๋ค.
์ดํฐ๋ ์ด์ ํ๋กํ ์ฝ์ ๋ค์ํ ๋ฐ์ดํฐ ๊ณต๊ธ์๊ฐ ํ๋์ ์ํ ๋ฐฉ์์ ๊ฐ๋๋ก ๊ท์ ํ์ฌ ๋ฐ์ดํฐ ์๋น์๊ฐ ํจ์จ์ ์ผ๋ก ๋ค์ํ ๋ฐ์ดํฐ ๊ณต๊ธ์๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ๋ฐ์ดํฐ ์๋น์์ ๋ฐ์ดํฐ ๊ณต๊ธ์๋ฅผ ์ฐ๊ฒฐํ๋ ์ธํฐํ์ด์ค์ ์ญํ ์ ํ๋ค.
์ดํฐ๋ ์ด์ ํ๋กํ ์ฝ์ ์ค์ํ์ง ์๋ ์ผ๋ฐ ๊ฐ์ฒด๋ ์ดํฐ๋ ์ด์ ํ๋กํ ์ฝ์ ์ค์ํ๋๋ก ๊ตฌํํ๋ฉด ์ฌ์ฉ์ ์ ์ ์ดํฐ๋ฌ๋ธ์ด ๋๋ค.
// ํผ๋ณด๋์น ์์ด์ ๊ตฌํํ ์ฌ์ฉ์ ์ ์ ์ดํฐ๋ฌ๋ธ
const fibonacci = {
// Symbol.iterator ๋ฉ์๋๋ฅผ ๊ตฌํํ์ฌ ์ดํฐ๋ฌ๋ธ ํ๋กํ ์ฝ์ ์ค์ํ๋ค.
[Symbol.iterator]() {
let [pre, cur] = [0, 1]; // "36.1. ๋ฐฐ์ด ๋์คํธ๋ญ์ฒ๋ง ํ ๋น" ์ฐธ๊ณ
const max = 10; // ์์ด์ ์ต๋๊ฐ
// Symbol.iterator ๋ฉ์๋๋ next ๋ฉ์๋๋ฅผ ์์ ํ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐํํด์ผ ํ๊ณ
// next ๋ฉ์๋๋ ์ดํฐ๋ ์ดํฐ ๋ฆฌ์ ํธ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ผ ํ๋ค.
return {
next() {
[pre, cur] = [cur, pre + cur]; // "36.1. ๋ฐฐ์ด ๋์คํธ๋ญ์ฒ๋ง ํ ๋น" ์ฐธ๊ณ
// ์ดํฐ๋ ์ดํฐ ๋ฆฌ์ ํธ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
return { value: cur, done: cur >= max };
}
};
}
};
// ์ดํฐ๋ฌ๋ธ์ธ fibonacci ๊ฐ์ฒด๋ฅผ ์ํํ ๋๋ง๋ค next ๋ฉ์๋๊ฐ ํธ์ถ๋๋ค.
for (const num of fibonacci) {
console.log(num); // 1 2 3 5 8
}
์ฌ์ฉ์ ์ ์ ์ดํฐ๋ฌ๋ธ
์ ์ดํฐ๋ ์ด์
ํ๋กํ ์ฝ์ ์ค์ํ๋๋ก Symbol.iterator ๋ฉ์๋๋ฅผ ๊ตฌํ
ํ๊ณ Symbol.iterator ๋ฉ์๋๊ฐ next ๋ฉ์๋๋ฅผ ๊ฐ๋ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐํ
ํ๋๋ก ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ดํฐ๋ ์ดํฐ์ next ๋ฉ์๋๋ done๊ณผ value ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๋ ์ดํฐ๋ ์ดํฐ ๋ฆฌ์ ํธ ๊ฐ์ฒด๋ฅผ ๋ฐํ
ํ๋ค.
for...of ๋ฌธ์ done ํ๋กํผํฐ๊ฐ true๊ฐ ๋ ๋๊น์ง ๋ฐ๋ณตํ๋ฉฐ done ํ๋กํผํฐ๊ฐ true๊ฐ ๋๋ฉด ๋ฐ๋ณต์ธ ์ฆ์ง
์ดํฐ๋ฌ๋ธ์ for...of ๋ฌธ๋ฟ๋ง ์๋๋ผ ์คํ๋ ๋ ๋ฌธ๋ฒ, ๋ฐฐ์ด ๋์คํธ๋ญ์ฒ๋ง ํ ๋น์๋ ์ฌ์ฉ
์์์ ์ดํด๋ณธ fibonacci ์ดํฐ๋ฌ๋ธ์ ๋ด๋ถ์ ์์ด์ ์ต๋๊ฐ max๋ฅผ ๊ฐ์ง๊ณ ์๋ค. ์ด ์์ด์ ์ต๋๊ฐ์ ๊ณ ์ ๋ ๊ฐ์ผ๋ก ์ธ๋ถ์์ ์ ๋ฌํ ๊ฐ์ผ๋ก ๋ณ๊ฒฝํ ๋ฐฉ๋ฒ์ด ์๋ค๋ ์์ฌ์์ด ์๋ค. ์์ด์ด ์ต๋๊ฐ์ ์ธใ ๋ก ์ ๋ฌ๋ฐ์ ์ดํฐ๋ฌ๋ธ์ ๋ฐํํ๋ ํจ์๋ฅผ ๋ง๋ค์ด ๋ณด์.
// ํผ๋ณด๋์น ์์ด์ ๊ตฌํํ ์ฌ์ฉ์ ์ ์ ์ดํฐ๋ฌ๋ธ์ ๋ฐํํ๋ ํจ์. ์์ด์ ์ต๋๊ฐ์ ์ธ์๋ก ์ ๋ฌ๋ฐ๋๋ค.
const fibonacciFunc = function (max) {
let [pre, cur] = [0, 1];
// Symbol.iterator ๋ฉ์๋๋ฅผ ๊ตฌํํ ์ดํฐ๋ฌ๋ธ์ ๋ฐํํ๋ค.
return {
[Symbol.iterator]() {
return {
next() {
[pre, cur] = [cur, pre + cur];
return { value: cur, done: cur >= max };
}
};
}
};
};
// ์ดํฐ๋ฌ๋ธ์ ๋ฐํํ๋ ํจ์์ ์์ด์ ์ต๋๊ฐ์ ์ธ์๋ก ์ ๋ฌํ๋ฉด์ ํธ์ถํ๋ค.
for (const num of fibonacciFunc(10)) {
console.log(num); // 1 2 3 5 8
}
์ดํฐ๋ ์ดํฐ๋ฅผ ์์ฑํ๋ ค๋ฉด ์ดํฐ๋ฌ๋ธ์ Symbol.iterator ๋ฉ์๋๋ฅผ ํธ์ถํด์ผ ํ๋ค.
// fibonacciFunc ํจ์๋ ์ดํฐ๋ฌ๋ธ์ ๋ฐํํ๋ค.
const iterable = fibonacciFunc(5);
// ์ดํฐ๋ฌ๋ธ์ Symbol.iterator ๋ฉ์๋๋ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐํ
const iterator = iterable[Symbol.iterator]();
console.log(iterator.next()); // {value:1, done:false}
console.log(iterator.next()); // {value:2, done:false}
console.log(iterator.next()); // {value:3, done:false}
console.log(iterator.next()); // {value:5, done:true}
์ดํฐ๋ฌ๋ธ์ด๋ฉด์ ์ดํฐ๋ ์ดํฐ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฉด Symbol.iterator ๋ฉ์๋๋ฅผ ํธ์ถํ์ง ์์๋ ๋๋ค. ๋ค์ ๊ฐ์ฒด๋ Symbol.iterator ๋ฉ์๋์ next ๋ฉ์๋๋ฅผ ์์ ํ ์ดํฐ๋ฌ๋ธ์ด๋ฉด์ ์ดํฐ๋ ์ดํฐ๋ค. Symbol.iterator ๋ฉ์๋๋ this๋ฅผ ๋ฐํํ๋ฏ๋ก next ๋ฉ์๋๋ฅผ ๊ฐ๋ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐํ.
// ์ดํฐ๋ฌ๋ธ์ด๋ฉด์ ์ดํฐ๋ ์ดํฐ์ธ ๊ฐ์ฒด. ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐํํ๋ Symbol.iterator ๋ฉ์๋์
// ์ดํฐ๋ ์ด์
๋ฆฌ์ ํธ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ next ๋ฉ์๋๋ฅผ ์์ ํ๋ค.
{
[Symbol.iterator]() { return this; },
next() {
return { value: any, done: boolean };
}
}
// ์ดํฐ๋ฌ๋ธ์ด๋ฉด์ ์ดํฐ๋ ์ดํฐ์ธ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ํจ์
const fibonacciFunc = function (max) {
let [pre, cur] = [0, 1];
// Symbol.iterator ๋ฉ์๋์ next ๋ฉ์๋๋ฅผ ์์ ํ ์ดํฐ๋ฌ๋ธ์ด๋ฉด์ ์ดํฐ๋ ์ดํฐ์ธ ๊ฐ์ฒด๋ฅผ ๋ฐํ
return {
[Symbol.iterator]() { return this; },
// next ๋ฉ์๋๋ ์ดํฐ๋ ์ดํฐ ๋ฆฌ์ ํธ ๊ฐ์ฒด๋ฅผ ๋ฐํ
next() {
[pre, cur] = [cur, pre + cur];
return { value: cur, done: cur >= max };
}
};
};
// iter๋ ์ดํฐ๋ฌ๋ธ์ด๋ฉด์ ์ดํฐ๋ ์ดํฐ๋ค.
let iter = fibonacciFunc(10);
// iter๋ ์ดํฐ๋ฌ๋ธ์ด๋ฏ๋ก for...of ๋ฌธ์ผ๋ก ์ํํ ์ ์๋ค.
for (const num of iter) {
console.log(num); // 1 2 3 5 8
}
// iter๋ ์ดํฐ๋ฌ๋ธ์ด๋ฉด์ ์ดํฐ๋ ์ดํฐ๋ค
iter = fibonacciFunc(10);
// iter๋ ์ดํฐ๋ ์ดํฐ์ด๋ฏ๋ก ์ดํฐ๋ ์ด์
๋ฆฌ์ ํธ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ next ๋ฉ์๋๋ฅผ ์์ ํ๋ค.
console.log(iter.next()); // { value: 1, done: false }
console.log(iter.next()); // { value: 2, done: false }
console.log(iter.next()); // { value: 3, done: false }
console.log(iter.next()); // { value: 5, done: false }
console.log(iter.next()); // { value: 8, done: false }
console.log(iter.next()); // { value: 13, done: true }
๋ฌดํ ์ดํฐ๋ฌ๋ธ์ ์์ฑํ๋ ํจ์๋ฅผ ํตํด ๋ฌดํ ์์ด์ ๊ฐ๋จํ ๊ตฌํํ ์ ์๋ค.
// ๋ฌดํ ์ดํฐ๋ฌ๋ธ์ ์์ฑํ๋ ํจ์
const fibonacciFunc = function () {
let [pre, cur] = [0, 1];
return {
[Symbol.iterator]() { return this; },
next() {
[pre, cur] = [cur, pre + cur];
// ๋ฌดํ์ ๊ตฌํํด์ผ ํ๋ฏ๋ก done ํ๋กํผํฐ๋ฅผ ์๋ตํ๋ค.
return { value: cur };
}
};
};
// fibonacciFunc ํจ์๋ ๋ฌดํ ์ดํฐ๋ฌ๋ธ์ ์์ฑํ๋ค.
for (const num of fibonacciFunc()) {
if (num > 10000) break;
console.log(num); // 1 2 3 5 8...4181 6765
}
// ๋ฐฐ์ด ๋์คํธ๋ญ์ฒ๋ง ํ ๋น์ ํตํด ๋ฌดํ ์ดํฐ๋ฌ๋ธ์์ 3๊ฐ์ ์์๋ง ์ทจ๋ํ๋ค.
const [f1, f2, f3] = fibonacciFunc();
console.log(f1, f2, f3); // 1 2 3
์ ์์ ์ ์ดํฐ๋ฌ๋ธ์ ์ง์ฐ ํ๊ฐ๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์์ฑ ์ง์ฐ ํ๊ฐ๋ ๋ฐ์ดํฐ๊ฐ ํ์ํ ์์ ์ด์ ๊น์ง๋ ๋ฏธ๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ์ง ์๋ค๊ฐ ๋ฐ์ดํฐ๊ฐ ํ์ํ ์์ ์ด ๋๋ฉด ๊ทธ๋์ผ ๋น๋ก์ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๋ ๊ธฐ๋ฒ์ด๋ค. ์ฆ ํ๊ฐ ๊ฒฐ๊ณผ๊ฐ ํ์ํ ๋๊น์ง ํ๊ฐ๋ฅผ ๋ฆ์ถ๋ ๊ธฐ๋ฒ์ด ์ง์ฐ ํ๊ฐ๋ค.
์ง์ฐ ํ๊ฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ถํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌ ์์ฑํ์ง ์๊ณ
ํ์ํ ๋ฐ์ดํฐ๋ฅผ ํ์ํ ์๊ฐ์ ์์ฑํ๋ฏ๋ก ๋น ๋ฅธ ์คํ ์๋
๋ฅผ ๊ธฐ๋ํ ์ ์๊ณ ๋ถํ์ํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋นํ์ง ์์ผ๋ฉฐ
๋ฌดํ๋ ํํ
ํ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค.