ํด๋ก์
๋ ๋ํดํ๊ธฐ๋ก ์ ๋ช ํ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ ์ค ํ๋, ์๋ฐ์คํฌ๋ฆฝํธ ๊ณ ์ ์ ๊ฐ๋ ์ ์๋๋ค.
ํด๋ก์
๋ ํจ์๋ฅผ ์ผ๊ธ ๊ฐ์ฒด๋ก ์ทจ๊ธํ๋ํจ์ํ ํ๋ก๊ทธ๋๋ฐ
์ธ์ด์์ ์ฌ์ฉ๋๋ ์ค์ํ ํน์ฑ์ด๋ค.
ํด๋ก์
๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ณ ์ ์ ๊ฐ๋ ์ด ์๋๋ฏ๋กECMAScript
์ฌ์์ ๋ฑ์ฅํ์ง ์๋๋ค.MDN
์์๋ ํด๋ก์ ์ ๋ํด ๋ค์๊ณผ ๊ฐ์ด ์ ์ํ๊ณ ์๋ค.
"ํด๋ก์ ๋ ํจ์์ ๊ทธ ํจ์๊ฐ ์ ์ธ๋ ๋ ์์ปฌ ํ๊ฒฝ๊ณผ์ ์กฐํฉ์ด๋ค".
ํด๋ก์
๋ฅผ ์ดํดํ๋ ค๋ฉด ๋จผ์ ๋ ์์ปฌ ํ๊ฒฝ
, ์ฆ๋ ์์ปฌ ์ค์ฝํ
๋ฅผ ์ดํดํด์ผ ํ๋ค.
const x = 1;
function outerFunc() {
const x = 10;
function innerFunc() {
console.log(x); // 10
}
innerFunc();
}
outerFunc();
const x = 1;
function outerFunc() {
const x = 10;
innerFunc();
}
function innerFunc() {
console.log(x); // 1
}
outerFunc()
์๋ฐ์คํฌ๋ฆฝํธ๋ ๋ ์์ปฌ ์ค์ฝํ๋ฅผ ๋ฐ๋ฅด๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ด๋ค.
๋ ์์ปฌ ์ค์ฝํ
๋ฅผ์คํ ์ปจํ ์คํธ
์ ๊ด์ ์์ ์ดํด๋ณด์.
์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ํจ์๋ฅผ ์ด๋์ ํธ์ถํ๋์ง๊ฐ ์๋๋ผ ํจ์๋ฅผ ์ด๋์ ์ ์ํ๋์ง์ ๋ฐ๋ผ ์์ ์ค์ฝํ๋ฅผ ๊ฒฐ์ ํ๋ค. ์ด๋ฅผ๋ ์์ปฌ ์ค์ฝํ(์ ์ ์ค์ฝํ)
๋ผ ํ๋ค.
๋ ์์ปฌ ํ๊ฒฝ์ "์ธ๋ถ ๋ ์์ปฌ ํ๊ฒฝ์ ๋ํ ์ฐธ์กฐ"์ ์ ์ฅํ ์ฐธ์กฐ๊ฐ. ์ฆ ์์ ์ค์ฝํ์ ๋ํ ์ฐธ์กฐ๋ ํจ์ ์ ์๊ฐ ํ๊ฐ๋๋ ์์ ์ ํจ์๊ฐ ์ ์๋ ํ๊ฒฝ(์์น)์ ์ํด ๊ฒฐ์ ๋๋ค. ์ด๊ฒ์ด ๋ฐ๋ก๋ ์์ปฌ ์ค์ฝํ
๋ค.
[[Environment]]
ํจ์๊ฐ ์ ์ ํ๊ฒฝ(์์น)๊ณผ ํธ์ถ๋๋ ํ๊ฒฝ(์์น)๋ ๋ค๋ฅผ ์ ์๋ค. ๋ฐ๋ผ์ ๋ ์์ปฌ ์ค์ฝํ๊ฐ ๊ฐ๋ฅํ๋ ค๋ฉด ํจ์๋ ์์ ์ด ํธ์ถ๋๋ ํ๊ฒฝ๊ณผ๋ ์๊ด์์ด ์์ ์ด ์ ์๋ ํ๊ฒฝ, ์ฆ ์์ ์ค์ฝํ(ํจ์ ์ ์๊ฐ ์์นํ๋ ์ค์ฝํ๊ฐ ๋ฐ๋ก ์์์ค์ฝํ)๋ฅผ ๊ธฐ์ตํด์ผ ํ๋ค.
์ด๋ฅผ ์ํด ํจ์๋ ์์ ์ ๋ด๋ถ ์ฌ๋กฏ[[Envirnoment]]
์ ์์ ์ด ์ ์๋ ํ๊ฒฝ, ์ฆ ์์ ์ค์ฝํ์ ์ฐธ์กฐ๋ฅผ ์ ์ฅํ๋ค.
์์ ์[[Envirnoment]]
์ ์ ์ฅ๋ ์์ ์ค์ฝํ์ ์ฐธ์กฐ๋ ํ์ฌ ์คํ ์ค์ธ ์คํ ์ปจํ ์คํธ์ ๋ ์์ปฌํ๊ฒฝ์ ๊ฐ๋ฆฌํจ๋ค.
const x = 1;
function foo() {
const x = 10;
// ์์ ์ค์ฝํ๋ ํจ์ ์ ์ ํ๊ฒฝ(์์น)์ ๋ฐ๋ผ ๊ฒฐ์ ๋๋ค.
// ํจ์ ํธ์ถ ์์น์ ์์ ์ค์ฝํ๋ ์๋ฌด๋ฐ ๊ด๊ณ๊ฐ ์๋ค.
bar();
}
// ํจ์ bar๋ ์์ ์ ์์ ์ค์ฝํ, ์ฆ ์ ์ญ ๋ ์์ปฌ ํ๊ฒฝ์ [[Environment]]์ ์ฅํ์ฌ ๊ธฐ์ตํ๋ค.
function bar() {
console.log(x);
}
foo()
bar()
๊ทธ๋ฆผ์ โ ์ ์ ์ญ ์ฝ๋ ํ๊ฐ ์์ ์์
foo
์barํจ์
๊ฐ์ฒด๊ฐ ์์ฑ๋๋ฉฐ ๊ฐ ํจ์ ๊ฐ์ฒด์ ๋ด๋ถ ์ฌ๋กฏ[[Environment]]
์ ์์ ์ค์ฝํ๊ฐ ์ ์ฅ๋๋ค.
fooํจ์
๊ฐ ํธ์ถ๋๋ฉด โกfooํจ์
์ ๋ ์์ปฌ ํ๊ฒฝ์ด ์์ฑ๋๋ฉฐ ์ธ๋ถ ๋ ์์ปฌ ํ๊ฒฝ ํ๊ฒฝ์ ๋ํ ์ฐธ์กฐ์ ์ ์ญ ๋ ์์ปฌ ํ๊ฒฝ์ ์ฐธ์กฐ(ํจ์ ๊ฐ์ฒด์ ๋ด๋ถ ์ฌ๋กฏ[[Environment]]
์ ์ ์ฅ๋)๊ฐ ์ ์ฅ๋๋ค.
barํจ์
๊ฐ ํธ์ถ๋๋ฉด โขbarํจ์
์ ๋ ์์ปฌ ํ๊ฒฝ์ด ์์ฑ๋๋ฉฐ ์ธ๋ถ ๋ ์์ปฌ ํ๊ฒฝ ํ๊ฒฝ์ ๋ํ ์ฐธ์กฐ์ ์ ์ญ ๋ ์์ปฌ ํ๊ฒฝ์ ์ฐธ์กฐ(ํจ์ ๊ฐ์ฒด์ ๋ด๋ถ ์ฌ๋กฏ[[Environment]]
์ ์ ์ฅ๋)๊ฐ ์ ์ฅ๋๋ค.
์ธ๋ถ ํจ์๋ณด๋ค ์ค์ฒฉ ํจ์๊ฐ ๋ ์ค๋ ์ ์ง๋๋ ๊ฒฝ์ฐ ์ค์ฒฉ ํจ์๋ ์ด๋ฏธ ์๋ช ์ฃผ๊ธฐ๊ฐ ์ข ๋ฃํ ์ธ๋ถ ํจ์์ ๋ณ์๋ฅผ ์ฐธ์กฐํ ์ ์๋ค. ์ด๋ฌํ ์ค์ฒฉ ํจ์๋ฅผ
ํด๋ก์
๋ผ๊ณ ๋ถ๋ฅธ๋ค.
ํด๋ก์
์ ๋ํ MDN์ ์ ์๋ "ํด๋ก์ ๋ ํจ์์ ๊ทธ ํจ์๊ฐ ์ ์ธ๋ ๋ ์์ปฌ ํ๊ฒฝ๊ณผ์ ์กฐํฉ์ด๋ค." ์ฌ๊ธฐ์ "ํจ์๊ฐ ์ ์ธ๋ ๋ ์์ปฌ ํ๊ฒฝ"์ด๋ ํจ์๊ฐ ์ ์๋ ์์น์ ์ค์ฝํ, ์ฆ ์์ ์ค์ฝํ๋ฅผ ์๋ฏธํ๋ ์คํ ์ปจํ ์คํธ์ ๋ ์์ปฌ ํ๊ฒฝ์ ๋งํ๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์ ๋ชจ๋ ํจ์๋ ์์ ์ ์์ ์ค์ฝํ๋ฅผ ๊ธฐ์ตํ๋ค. ๋ชจ๋ ํจ์๊ฐ ๊ธฐ์ตํ๋ ์์ ์ค์ฝํ๋ ํจ์๋ฅผ ์ด๋์ ํธ์ถํ๋ ์๊ด์์ด ์ ์ง๋๋ค.
๋ฐ๋ผ์ ํจ์๋ฅผ ์ด๋์ ํธ์ถํ๋ ์๊ด์์ด ํจ์๋ ์ธ์ ๋ ์์ ์ด ๊ธฐ์ตํ๋ ์์ ์ค์ฝํ์ ์๋ณ์๋ฅผ ์ฐธ์กฐํ ์ ์์ผ๋ฉฐ ์๋ณ์์ ๋ฐ์ธ๋ฉ๋ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ค.
const x = 1;
// โ
function outer() {
const x = 10;
const inner = function () { console.log(x); }; // โก
return inner;
}
// outer ํจ์๋ฅผ ํธ์ถํ๋ฉด ์ค์ฒฉ ํจ์ inner๋ฅผ ๋ฐํํ๋ค.
// ๊ทธ๋ฆฌ๊ณ outer ํจ์์ ์คํ ์ปจํ
์คํธ๋ ์คํ ์ปจํ
์คํธ ์คํ์์ ํ๋์ด ์ ๊ฑฐ๋๋ค.
const innerFunc = outer(); // โข
innerFunc(); // โฃ 10
โข์์
outerํจ์
๋ฅผ ํธ์ถํ๋ฉดouterํจ์
๋์ค์ฒฉ ํจ์inner
๋ฅผ ๋ฐํํ๊ณ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๋ง๊ฐํ๋ค. ์ฆ,outerํจ์
์ ์คํ ์ปจํ ์คํธ๋ ์คํ ์ปจํ ์คํธ ์คํ์์ ์ ๊ฑฐ๋๋ค.
์ด๋outerํจ์
์์ง์ญ ๋ณ์ x
๋ํ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๋ง๊ฐํ๋ค.
๊ทธ๋ฌ๋ โฃ์์innerํจ์
ํธ์ถ ๊ฒฐ๊ณผ๋outerํจ์
์์ง์ญ ๋ณ์ x
์ ๊ฐ์ธ 10์ด๋ค. ์ด๋ฏธ ์๋ช ์ฃผ๊ธฐ๊ฐ ์ข ๋ฃ๋์ด ์คํ ์ปจํ ์คํธ ์คํ์์ ์ ๊ฑฐ๋outerํจ์
์์ง์ญ ๋ณ์ x
๊ฐ ๋ค์ ๋ถํ์ด๋ผ๋ ํ๋ฏ ๋์ํ๋ค.
1.์ ์ญ ์ฝ๋ ์คํ(outer๊ฐ์ฒด ์์ฑ)
2.outerํจ์ ํธ์ถ(inner๊ฐ์ฒด ์์ฑ ๋ฐ ๋ฐํ)
3.innerFunc ์ ์ญ ๋ณ์์ innerํจ์ ์ฐธ์กฐ ํ ๋น
outer ํจ์
์ ์คํ์ด ์ข ๋ฃ๋๋ฉดinner ํจ์
๋ฅผ ๋ฐํํ๋ฉด์outer ํจ์
์ ์๋ช ์ฃผ๊ธฐ๊ฐ ์ข ๋ฃ ์ฆ,outer ํจ์
์ ์คํ ์ปจํ ์คํธ๊ฐ ์คํ ์ปจํ ์คํธ ์คํ์์ ์ ๊ฑฐ๋๋ค.
์ด๋outer ํจ์
์ ์คํ ์ปจํ ์คํธ๋ ์คํ ์ปจํ ์คํธ ์คํ์์ ์ ๊ฑฐ๋์ง๋งouter ํจ์
์ ๋ ์์ปฌ ํ๊ฒฝ๊น์ง ์๋ฉธํ๋ ๊ฒ์ ์๋๋ค
outer ํจ์
์ ๋ ์์ปฌ ํ๊ฒฝ์inner ํจ์
์[[Environment]]
๋ด๋ถ ์ฌ๋กฏ์ ์ํด ์ฐธ์กฐ๋์ด ์๊ณinner ํจ์
๋์ ์ญ ๋ณ์ innerFunc
์ ์ํด ์ฐธ์กฐ๋๊ณ ์์ผ๋ฏ๋ก ๊ฐ๋น์ง ์ปฌ๋ ์ ์ ๋์์ด ๋์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ฐ๋น์ง ์ปฌ๋ ํฐ๋ ๋๊ตฐ๊ฐ๊ฐ ์ฐธ์กฐํ๊ณ ์๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ํจ๋ถ๋ก ํด์ ํ์ง ์๋๋ค.
4.innerFunc
ํธ์ถ๋ก innerํจ์
์ ๋ ์์ปฌ ํ๊ฒฝ ์์ฑ(innerํจ์ ๊ฐ์ฒด์ [[Environment]]
๋ด๋ถ ์ฌ๋กฏ ์ฐธ์กฐ)
outer ํจ์
๊ฐ ๋ฐํํinner ํจ์
๋ฅผ ํธ์ถ ํ๋ฉดinner ํจ์
์ ์คํ ์ปจํ ์คํธ๊ฐ ์์ฑ๋๊ณ ์คํ ์ปจํ ์คํธ ์คํ์ ํธ์๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ ์์ปฌ ํ๊ฒฝ์ ์ธ๋ถ ๋ ์์ปฌ ํ๊ฒฝ์ ๋ํ ์ฐธ์กฐ์๋inner ํจ์ ๊ฐ์ฒด
์[[Environment]]
๋ด๋ถ ์ฌ๋กฏ์ ์ ์ฅ๋์ด ์๋ ์ฐธ์กฐ๊ฐ์ด ํ ๋น.
์๋ฐ์คํฌ๋ฆฝํธ์ ๋ชจ๋ ํจ์๋ ์์ ์ค์ฝํ๋ฅผ ๊ธฐ์ตํ๋ฏ๋ก ์ด๋ก ์ ์ผ๋ก ๋ชจ๋ ํจ์๋ํด๋ก์
๋ค. ํ์ง๋ง ์ผ๋ฐ์ ์ผ๋ก ๋ชจ๋ ํจ์๋ฅผํด๋ก์
๋ผ๊ณ ํ์ง๋ ์๋๋ค.
<!DOCTYPE html>
<html>
<body>
<script>
function foo() {
const x = 1;
const y = 2;
// ์ผ๋ฐ์ ์ผ๋ก ํด๋ก์ ๋ผ๊ณ ํ์ง ์๋๋ค.
function bar() {
const z = 3;
debugger;
// ์์ ์ค์ฝํ์ ์๋ณ์๋ฅผ ์ฐธ์กฐํ์ง ์๋๋ค.
console.log(z);
}
return bar;
}
const bar = foo();
bar();
</script>
</body>
</html>
์์ ์ค์ฝํ์ ์๋ณ์
x , y
๋ฅผ ์ฐธ์กฐํ์ง ์์์ผ๋ฏ๋กํด๋ก์
๋ผ ํ ์ ์๋ค.
์์ ์ค์ฝํ์ ์ด๋ค ์๋ณ์๋ ์ฐธ์กฐํ์ง ์๋ ๊ฒฝ์ฐ ๋๋ถ๋ถ์ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ๋ ์ต์ ํ๋ฅผ ํตํด ๋ค์๊ณผ ๊ฐ์ด ์์ ์ค์ฝํ๋ฅผ ๊ธฐ์ตํ์ง ์๋๋ค. ์ฐธ์กฐํ์ง ์๋ ์๋ณ์๋ฅผ ๊ธฐ์ตํ๋ ๊ฒ์ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น์ด๊ธฐ ๋๋ฌธ์ด๋ค.
<!DOCTYPE html>
<html>
<body>
<script>
function foo() {
const x = 1;
// ์ผ๋ฐ์ ์ผ๋ก ํด๋ก์ ๋ผ๊ณ ํ์ง ์๋๋ค.
// bar ํจ์๋ ํด๋ก์ ์์ง๋ง ๊ณง๋ฐ๋ก ์๋ฉธํ๋ค.
function bar() {
debugger;
// ์์ ์ค์ฝํ์ ์๋ณ์๋ฅผ ์ฐธ์กฐํ๋ค.
console.log(x);
}
bar();
}
foo();
</script>
</body>
</html>
์์ ์ค์ฝํ์ ์๋ณ์๋ฅผ ์ฐธ์กฐํ๊ณ ์์ผ๋ฏ๋ก
ํด๋ก์
๋ค. ํ์ง๋ง์ธ๋ถ ํจ์ foo
๋ณด๋ค์ค์ฒฉ ํจ์ bar
์ ์๋ช ์ฃผ๊ธฐ๊ฐ ์งง๋ค.
์ด๋ฐ ๊ฒฝ์ฐ ์ผ๋ฐ์ ์ผ๋กํด๋ก์
๋ผ๊ณ ํ์ง ์๋๋ค.
<!DOCTYPE html>
<html>
<body>
<script>
function foo() {
const x = 1;
const y = 2;
// ํด๋ก์
// ์ค์ฒฉ ํจ์ bar๋ ์ธ๋ถ ํจ์๋ณด๋ค ๋ ์ค๋ ์ ์ง๋๋ฉฐ ์์ ์ค์ฝํ์ ์๋ณ์๋ฅผ ์ฐธ์กฐํ๋ค.
function bar() {
debugger;
console.log(x);
}
return bar;
}
const bar = foo();
bar();
</script>
</body>
</html>
ํด๋ก์
๋ ์ค์ฒฉ ํจ์๊ฐ ์์ ์ค์ฝํ์ ์๋ณ์๋ฅผ ์ฐธ์กฐํ๊ณ ์๊ณ ์ค์ฒฉ ํจ์๊ฐ ์ธ๋ถ ํจ์๋ณด๋ค ๋ ์ค๋ ์ ์ง๋๋ ๊ฒฝ์ฐ์ ํ์ ๋๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค.
์์ ์คํฌํฌ์x, y ์๋ณ์
์ค์์ x๋ง ์ฐธ์กฐ ์ด๋ฐ ๊ฒฝ์ฐ ๋๋ถ๋ถ์ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ๋ ์ต์ ํ๋ฅผ ํตํด ์์ ์ค์ฝํ์ ์๋ณ์ ์ค์์ ํด๋ก์ ๊ฐ ์ฐธ์กฐํ๊ณ ์๋ ์๋ณ์๋ง์ ๊ธฐ์ตํ๋ค.
ํด๋ก์
์ ์ํด ์ฐธ์กฐ๋๋ ์์ ์ค์ฝํ์ ๋ณ์๋ฅผ ์์ ๋ณ์๋ผ๊ณ ๋ถ๋ฅธ๋ค.
ํด๋ก์
๋ "ํจ์๊ฐ ์์ ๋ณ์์ ๋ํด ๋ซํ์๋ค"๋ผ๋ ์๋ฏธ๋ค. ์ด๋ฅผ ์ข ๋ ์๊ธฐ ์ฝ๊ฒ ์์ญํ์ง๋ง๋ "์์ ๋ณ์์ ๋ฌถ์ฌ์๋ ํจ์"๋ผ๊ณ ํ ์ ์๋ค.
ํด๋ก์
๋ ์ํ๋ฅผ ์์ ํ๊ฒ ๋ณ๊ฒฝํ๊ณ ์ ์งํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค. ๋ค์ ๋งํด, ์ํ๊ฐ ์๋์น ์๊ฒ ๋ณ๊ฒฝ๋์ง ์๋๋ก ์ํ๋ฅผ ์์ ํ๊ฒ ์๋ํ๊ณ ํน์ ํจ์์๊ฒ๋ง ์ํ ๋ณ๊ฒฝ์ ํ์ฉํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค.
// ์นด์ดํธ ์ํ ๋ณ์
let num = 0;
// ์นด์ดํธ ์ํ ๋ณ๊ฒฝ ํจ์
const increase = function ( {
// ์นด์ดํธ ์ํ๋ฅผ 1๋งํผ ์ฆ๊ฐ์ํจ๋ค.
return ++num;
};
์ ์ฝ๋๋ ์ ๋์ํ์ง๋ง ์ค๋ฅ๋ฅผ ๋ฐ์์ํฌ ๊ฐ๋ฅ์ฑ์ ๋ดํฌํ๊ณ ์๋ ์ข์ง ์์ ์ฝ๋ ๊ทธ ์ด์ ๋ ๋ค์์ ์ ์ ์กฐ๊ฑด์ด ์ง์ผ์ค์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
1. ์นด์ดํธ ์ํ(num ๋ณ์์ ๊ฐ)๋ increase ํจ์๊ฐ ํธ์ถ๋๊ธฐ ์ ๊น์ง ๋ณ๊ฒฝ๋์ง ์๊ณ ์ ์ง๋์ด์ผ ํ๋ค.
2. ์ด๋ฅผ ์ํด ์นด์ฐํธ ์ํ(num ๋ณ์์ ๊ฐ)๋ increase ํจ์๋ง์ด ๋ณ๊ฒฝํ ์ ์์ด์ผ ํ๋ค.
ํ์ง๋ง num ๋ณ์๋ ์ ์ญ ๋ณ์๋ก ์ธ์ ๋ ์ง ๋๊ตฌ๋ ์ ๊ทผํ ์ ์๊ณ ๋ณ๊ฒฝํ ์ ์๋ค. ๋ฐ๋ผ์ ์นด์ดํธ ์ํ๋ฅผ ์์ ํ๊ฒ ๋ณ๊ฒฝํ๊ณ ์ ์งํ๊ธฐ์ํด์๋increase ํจ์
๋ง์ด num ๋ณ์๋ฅผ ์ฐธ์กฐํ๊ณ ๋ณ๊ฒฝ ํ ์ ์๊ฒ ํ๋ ๊ฒ์ด ๋ฐ๋์งํ๋ค.
const increase = function () {
// ์นด์ดํธ ์ํ ๋ณ์
let num = 0;
// ์นด์ดํธ ์ํ๋ฅผ 1๋งํผ ์ฆ๊ฐ์ํจ๋ค.
retrun ++num;
};
// ์ด์ ์ํ๋ฅผ ์ ์งํ์ง ๋ชปํ๋ค.
console.log(increase()); // 1
console.log(increase()); // 1
console.log(increase()); // 1
์ ์ญ ๋ณ์
num
์increase
ํจ์์ ์ง์ญ๋ณ์๋ก ๋ณ๊ฒฝํ์ฌ ์๋์น ์์ ์ํ ๋ณ๊ฒฝ์ ๋ฐฉ์งํ๋ค.
ํ์ง๋งincrease
ํจ์๊ฐ ํธ์ถ๋ ๋๋ง๋ค ์ง์ญ ๋ณ์num
์ ๋ค์ ์ ์ธ๋๊ณ ์ด๊ธฐํ๋๋ค. ๋ค์๋งํด, ์ํ๊ฐ ๋ณ๊ฒฝ๋๊ธฐ ์ด์ ์ํ๋ฅผ ์ ์งํ์ง ๋ชปํ๋ค.
// ์นด์ดํธ ์ํ ๋ณ๊ฒฝ ํจ์
const increase = (function () {
// ์นด์ดํธ ์ํ ๋ณ์
let num = 0;
// ํด๋ก์
return function () {
// ์นด์ดํธ ์ํ๋ฅผ 1๋งํผ ์ฆ๊ฐ์ํจ๋ค.
return ++num;
};
}());
console.log(increase());
console.log(increase());
console.log(increase());
์ ์์ ๋
ํด๋ก์
์ด๋ค.
์ฆ์ ์คํ ํจ์๋ก ํธ์ถ๋ ์ดํ ์๋ฉธ๋๊ณ ๋ฐํํํด๋ก์
๋increase
๋ณ์์ ํ ๋น.
ํด๋ก์
๋ num
๋ณ์๊ฐ ์๋์น ํ๊ฒ ๋ณ๊ฒฝ๋์ง ์๋๋ก ์์ ํ๊ฒ ์๋ํ๊ณ ํน์ ํจ์์๊ฒ๋ง ์ํ ๋ณ๊ฒฝ์ ํ์ํ์ฌ ์ํ๋ฅผ ์์ ํ๊ฒ ๋ณ๊ฒฝํ๊ณ ์ ์งํ๊ธฐ์ํด ์ฌ์ฉ๋๋ค.
const counter = (function () {
// ์นด์ดํธ ์ํ ๋ณ์
let num = 0;
// ํด๋ก์ ์ธ ๋ฉ์๋๋ฅผ ๊ฐ๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
// ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ์ค์ฝํ๋ฅผ ๋ง๋ค์ง ์๋๋ค.
// ๋ฐ๋ผ์ ์๋ ๋ฉ์๋๋ค์ ์์ ์ค์ฝํ๋ ์ฆ์ ์คํ ํจ์์ ๋ ์์ปฌ ํ๊ฒฝ์ด๋ค.
return {
// num: 0, // ํ๋กํผํฐ๋ punlicํ๋ฏ๋ก ์๋๋์ง ์๋๋ค.
increase() retrun ++num;
},
decrease() {
return num > 0 ? --num : 0;
}
};
}();
console.log(counter.increase()); // 1
console.log(counter.increase()); // 2
console.log(counter.decrease()); // 1
console.log(counter.decrease()); // 0
const Counter = (function () {
//
let num = 0;
function Counter() {
// this.num = 0; // ํ๋กํผํฐ๋ publicํ๋ฏ๋ก ์๋๋์ง ์๋๋ค.
}
Counter.prototype.increase = function () {
ruturn ++num;
};
Counter.prototype.decrease = function () {
return num > 0 > --num : 0;
};
return Counter;
}());
const counter = new Counter();
console.log(counter.increase()); // 1
console.log(counter.increase()); // 2
console.log(counter.decrease()); // 1
console.log(counter.decrease()); // 0
increase
,decrease
๋ฉ์๋๋ํ๋กํ ํ์ ๋ฉ์๋
์ด๋ค.
์ด ๋ฉ์๋๋ค์ด ํ๊ฐ๋์ด ํจ์ ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋ ์คํ ์ค์ธ ์คํ ์ปจํ ์คํธ๋ ์ฆ์ ์คํ ํจ์์ ์คํ ์ปจํ ์คํธ์ด๋ค. ๋ฐ๋ผ์increase
,decrease
๋ฉ์๋๋ ์ฆ์ ์คํ ํจ์์ ์คํ ์ปจํ ์คํธ์ ๋ ์์ปฌ ํ๊ฒฝ์ ๊ธฐ์ตํ๋ ํด๋ก์ ์ด๋ค.
๋ค์ ๋งํ๋ฉดnum
๋ณ์์ ๊ฐ์increase
์decrease
๋ฉ์๋๋ง์ด ๋ณ๊ฒฝํ ์ ์๋ค.
โ ๊ณ ์ฐจ ํจ์๋?
๋ณด์กฐ ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ๊ณ ํจ์๋ฅผ ๋ฐํํ๋ ํจ์
// ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ๊ณ ํจ์๋ฅผ ๋ฐํํ๋ ๊ณ ์ฐจํจ์
// ์ด ํจ์๋ ์นด์ดํธ ์ํ๋ฅผ ์ ์งํ๊ธฐ ์ํ ์์ ๋ณ์ counter๋ฅผ ๊ธฐ์ตํ๋ ํด๋ก์ ๋ฅผ ๋ฐํํ๋ค.
function makeCounter(aux) {
// ์นด์ดํธ ์ํ๋ฅผ ์ ์งํ๊ธฐ ์ํ ์ฅ์ ๋ณ์
let counter = 0;
// ํด๋ก์ ๋ฅผ ๋ฐํ
return function () {
// ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๋ณด์กฐ ํจ์์ ์ํ ๋ณ๊ฒฝ์ ์์ํ๋ค.
counter = aux(counter);
return counter;
};
}
// ๋ณด์กฐ ํจ์
function increase(n) {
return ++n;
}
// ๋ณด์กฐ ํจ์
function decrease(n) {
return --n;
}
// ํจ์๋ก ํจ์๋ฅผ ์์ฑํ๋ค.
// makeCounter ํจ์๋ ๋ณด์กฐ ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ์ ํจ์๋ฅผ ๋ฐํํ๋ค.
const increaser = makeCounter(increase); // โ
console.log(increaser()); // 1
console.log(increaser()); // 2
// increaser ํจ์์๋ ๋ณ๊ฐ์ ๋
๋ฆฝ๋ ๋ ์์ปฌ ํ๊ฒฝ์ ๊ฐ๊ธฐ ๋๋ฌธ์ ์นด์ดํฐ ์ํ๊ฐ ์ฐ๋ํ์ง ์๋๋ค.
const decreser = makeCounter(decrease);
console.log(decreaser());
console.log(decreaser());
makeCounter
ํจ์๋ ๋ณด์กฐ ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ๊ณ ํจ์๋ฅผ ๋ฐํํ๋ ๊ณ ์ฐจ ํจ์
makeCounter
ํจ์๊ฐ ๋ฐํํ๋ ํจ์๋ ํจ์๋counter
๋ณ์๋ฅผ ๊ธฐ์ตํ๋ํด๋ก์
๋ค.
! ์ฃผ์ํด์ผ ํ ๊ฒ์makeCounter
ํจ์๋ฅผ ํธ์ถํด ํจ์๋ฅผ ๋ฐํํ ๋ ๋ฐํ๋ ํจ์๋ ์์ ๋ง์ ๋ ๋ฆฝ๋ ๋ ์์ปฌ ํ๊ฒฝ์ ๊ฐ๋๋ค๋ ๊ฒ์ด๋ค. ์ด๋ ํจ์๋ฅผ ํธ์ถํ๋ฉด ๊ทธ๋๋ง๋ค ์๋ก์ดmakeCounter
ํจ์ ์คํ ์ปจํ ์คํธ์ ๋ ์์ปฌ ํ๊ฒฝ์ด ์์ฑ๋๊ธฐ ๋๋ฌธ.
์ ์์ ์์ ์ ์ญ ๋ณ์
increaser
์decreaser
์ ํ ๋น๋ ํจ์๋ ๊ฐ๊ฐ ์์ ๋ง์ ๋ ๋ฆฝ๋ ๋ ์์ปฌ ํ๊ฒฝ์ ๊ฐ๊ธฐ ๋๋ฌธ์ ์นด์ดํธ๋ฅผ ์ ์งํ๊ธฐ ์ํ ์์ ๋ณ์counter
๋ฅผ ๊ณต์ ํ์ง ์์ ์นด์ดํฐ ์ฆ๊ฐ์ด ์ฐ๋๋์ง ์๋๋ค.
๋ฐ๋ผ์ ๋ ๋ฆณ๋ ์นด์ดํฐ๊ฐ ์๋๋ผ ์ฐ๋ํ์ฌ ์ฆ๊ฐ์ด ๊ฐ๋ฅํ ์นด์ดํฐ๋ฅผ ๋ง๋ค๋ ค๋ฉด ๋ ์์ปฌํ๊ฒฝ์ ๊ณต์ ํ๋ํด๋ก์
๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค. ์ด๋ฅผ ์ํด์๋makeCounter
ํจ์๋ฅผ ๋ ๋ฒ ํธ์ถํ์ง ๋ง์์ผ ํ๋ค.
// ํจ์๋ฅผ ๋ฐํํ๋ ๊ณ ์ฐจ ํจ์
// ์ด ํจ์๋ ์นด์ดํธ ์ํ๋ฅผ ์ ์งํ๊ธฐ ์ํ ์์ ๋ณ์ counter๋ฅผ ๊ธฐ์ตํ๋ ํด๋ก์ ๋ฅผ ๋ฐํํ๋ค.
const counter = (function () {
// ์นด์ดํธ ์ํ๋ฅผ ์ ์งํ๊ธฐ ์ํ ์์ ๋ณ์
let counter = 0;
// ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ๋ ํด๋ก์ ๋ฅผ ๋ฐํ
return function (aux) {
// ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๋ณด์กฐ ํจ์์ ์ํ ๋ณ๊ฒฝ์ ์์ํ๋ค.
counter = aux(counter)
return counter;
};
}());
// ๋ณด์กฐ ํจ์
function increase(n) {
return ++n;
}
// ๋ณด์กฐ ํจ์
function decrease(n) {
return --n;
}
// ๋ณด์กฐ ํจ์๋ฅผ ์ ๋ฌํ์ฌ ํธ์ถ
console.log(counter(increase)); // 1
console.log(counter(increase)); // 2
// ์์ ๋ณ์๋ฅผ ๊ณต์ ํ๋ค.
console.log(counter(decrease)); // 1
console.log(counter(decrease)); // 0
์บก์ํ
๋ ๊ฐ์ฒด์ ์ํ๋ฅผ ๋ํ๋ด๋ ํ๋กํผํฐ์ ํ๋กํผํฐ๋ฅผ ์ฐธ์กฐํ๊ณ ์กฑํ ์ ์๋ ๋์์ธ ๋ฉ์๋๋ฅผ ํ๋๋ก ๋ฌถ๋ ๊ฒ์ ๋งํ๋ค.์บก์ํ
๋ ๊ฐ์ฒด์ ํน์ ํ๋กํผํฐ๋ ๋ฉ์๋๋ฅผ ๊ฐ์ถ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ๋ ํ๋๋ฐ ์ด๋ฅผ์ ๋ณด ์๋
์ด๋ผ ํ๋ค.
์ ๋ณด ์๋
์ ์ธ๋ถ์ ๊ณต๊ฐํ ํ์๊ฐ ์๋ ๊ตฌํ์ ์ผ๋ถ๋ฅผ ์ธ๋ถ์ ๊ณต๊ฐ๋์ง ์๋๋ก ๊ฐ์ถ์ด ์ ์ ์น ๋ชปํ ์ ๊ทผ์ผ๋ก๋ถํฐ ๊ฐ์ฒด์ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ ๊ฒ์ ๋ฐฉ์งํด ์ ๋ณด๋ฅผ ๋ณดํธํ๊ณ , ๊ฐ์ฒด ๊ฐ์ ์ํธ ์์กด์ฑ, ์ฆ, ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๋ ํจ๊ณผ๊ฐ ์๋ค.
๋๋ถ๋ถ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ํด๋์ค๋ฅผ ์ ์ํ๊ณ ํด๋์ค๋ฅผ ๊ตฌ์ฑํ๋ ํ๋กํผํฐ์ ๋ฉ์๋์ ๋ํ์ฌpublic
private
protected
๊ฐ์ ์ ๊ทผ ์ ํ์๋ฅผ ์ ์ธํ์ฌ ๊ณต๊ฐ ๋ฒ์๋ฅผ ํ์ ํ ์ ์๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๋public
private
protected
๊ฐ์ ์ ๊ทผ ์ ํ์๋ฅผ ์ ๊ณตํ์ง ์๋๋ค. ๋ฐ๋ผ์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด์ ๋ชจ๋ ํ๋กํผํฐ์ ๋ฉ์๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ธ๋ถ์ ๊ณต๊ฐ๋์ด ์๋ค. ์ฆ, ๊ฐ์ฒด์ ๋ชจ๋ ํ๋กํผํฐ์ ๋ฉ์๋๋ ๊ธฐ๋ณธ์ ์ผ๋กpublic
ํ๋ค.
function Person(name, age) {
this.name = name; // public
let _age = age; // private
// ์ธ์คํด์ค ๋ฉ์๋
this.sayHi = function() {
console.log(`Hi! My name is ${this.name}. I am ${_age}.`);
};
}
const me = new Person('Lee', 20)
me.sayHi(); // Hi! My name is Lee. I am 20
console.log(me.name); // Lee
console.log(me._age); // undefined
const you = new Person('Kim', 30);
you.sayHi();
console.log(you.name); // Kim
console.log(you._age); // undefined
์ ์์
name
ํ๋กํผํฐ๋ ํ์ฌ ์ธ๋ถ๋ก ๊ณต๊ฐ๋์ด ์์ด ์์ ๋กญ๊ฒ ์ฐธ์กฐ ๋ณ๊ฒฝ ๊ฐ๋ฅ ์ฆ,name
ํ๋กํผํฐ๋publice
ํ๋ค.
ํ์ง๋ง_age
๋ณ์๋Person
์์ฑ์ ํจ์์ ์ง์ญ ๋ณ์์ด๋ฏ๋กPerson
์์ฑ์ ํจ์ ์ธ๋ถ์์ ์ฐธ์กฐํ๊ฑฐ๋ ๋ณ๊ฒฝํ ์ ์๋ค. ์ฆ,_age
๋ณ์๋private
ํ๋ค.
sayHi ๋ฉ์๋ ํ๋กํ ํ์ ์ผ๋ก ๋ณ๊ฒฝํ์ฌ sayHi ๋ฉ์๋์ ์ค๋ณต ์์ฑ์ ๋ฐฉ์ง
function Person(name, age) {
this.name = name; // public
let _age = age; // private
}
// ํ๋กํ ํ์
๋ฉ์๋
Person.prototype.sayHi = function () {
// Person ์์ฑ์ ํจ์์ ์ง์ญ ๋ณ์ _age๋ฅผ ์ฐธ์กฐํ ์ ์๋ค.
console.log(`Hi! My name is ${this.name}. I am ${_age}.`);
};
์ง์ญ ๋ณ์ _age
๋ฅผ ์ฐธ์กฐํ ์ ์๋ ๋ฌธ์ ํด๊ฒฐ.
const Person = (function () {
let _age = 0; // private
// ์์ฑ์ ํจ์
function Person(name, age) {
this.name = name; // public
_age = age;
}
// ํ๋กํ ํ์
๋ฉ์๋
Person.prototype.sayHi = function () {
console.log(`Hi My name is ${this.name}. I am ${_age}.`)
};
// ์์ฑ์ ํจ์๋ฅผ ๋ฐํ
return Person;
}());
์ ํจํด ์ฌ์ฉํ๋ฉด
public
private
protected
๊ฐ์ ์ ๊ธ ์ ํ์๋ฅผ ์ ๊ณตํ์ง ์๋ ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ์ ๋ณด ์๋์ด ๊ฐ๋ฅํ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค.
Person
์์ฑ์ ํจ์์sayHi
๋ฉ์๋๋ ์ด๋ฏธ ์ข ๋ฃ๋์ด ์๋ฉธํ ์ฆ์ ์คํ ํจ์์ ์ง์ญ ๋ณ์_age
๋ฅผ ์ฐธ์กฐํ ์ ์๋ํด๋ก์
๋ค.
ํ์ง๋ง ์ ์์ ๋ ์๋ฒฝํ์ง ์๋ค.
Person
์์ฑ์ ํจ์๊ฐ ์ฌ๋ฌ ๊ฐ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ๊ฒฝ์ฐ_age
๋ณ์์ ์ํ๊ฐ ์ ์ง๋์ง ์๋๋ค
const me = new Person('Lee', 20);
me.sayHi(); // Hi! My name is Lee. I am 20
const you = new Person('Kim', 30);
you.sayHi(); // Hi! My name is Kim. I am 30
// _age ๋ณ์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ค!
me.sayHi(); // Hi! My name is Lee I am 30.
์ฆ์ ์คํ ํจ์๋ก ๋ฐํ๋ ๋์ผํ ์์ ์ค์ฝํ๋ฅผ ์ฐธ์กฐํ๊ณ ์๊ธฐ ๋๋ฌธ.
// ์์ฃผ ๋ฐ์ํ ์ ์๋ ์ค์
var func = [];
for (var i = 0; i <3; i++); }
funcs[i] = function () { return i }; // โ
}
for (var j = 0; j func.length; j++) {
console.log(funcs[j]()); // โก
0
1
2
๋ฅผ ๋ฐํํ ๊ฒ์ผ๋ก ๊ธฐ๋ํ์ง๋ง ๊ฒฐ๊ณผ๋3
3
3
์ด ๋ฐํ๋์๋ค.
for
๋ฌธ์ ๋ณ์ ์ ์ธ๋ฌธ์์var
ํค์๋๋ก ์ ์ธํi
๋ณ์๋ ๋ธ๋ก๋ ๋ฒจ ์ค์ฝํ๊ฐ ์๋ ํจ์ ์ค์ฝํ ์ฆ, ์ ์ญ ๋ณ์๋ก ์ ์ธ๋์๊ธฐ ๋๋ฌธ์i
๊ฐ์ ์ ๋ฌํ์ฌ๋ ํธ์ถํ๋ ์์ ์์i
๊ฐ์ 3์ด๊ธฐ ๋๋ฌธ์ ์ํ๋ ๊ฒฐ๊ณผ๊ฐ์ ์ป์ง ๋ชปํ๋ค.
// ์ ์์ ๋ฅผ ํด๋ก์ ๋ก ๊ณ ์น๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
var funcs = [];
for (var i = 0; i < 3; i++){
funcs[i] = (function (id) { // โ
return function () {
return id;
};
}(i));
}
for (var j = 0; j < funcs.length; j++) {
console.log(funcs[j]()); // โก
}
โ ์์ ์ฆ์ ์คํ ํจ์๋ ์ ์ญ ๋ณ์
i
์ ํ์ฌ ํ ๋น๋์ด ์๋ ๊ฐ์ ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๋งค๊ฐ๋ณ์id
์ ํ ๋นํ ํ ์ค์ฒฉ ํจ์๋ฅผ ๋ฐํํ๊ณ ์ข ๋ฃ
์ด๋ ์ฆ์ ์คํ ํจ์์ ๋งค๊ฐ๋ณ์id
๋ ์ฆ์ ์คํ ํจ์๊ฐ ๋ฐํํ ์ค์ฒฉ ํจ์์ ์์ ์ค์ฝํ์ ์กด์ฌ. ์ฆ์ ์คํ ํจ์๊ฐ ๋ฐํํ ์ค์ฒฉ ํจ์๋ ์์ด์ ์ ์์ ์ค์ฝํ(์ฆ์ ์คํ ํจ์์ ๋ ์์ปฌ ํ๊ฒฝ)๋ฅผ ๊ธฐ์ตํ๋ ํด๋ก์ง์ด๊ณ , ๋งค๊ฐ๋ณ์id
๋ ์ฆ์ ์คํ ํจ์๊ฐ ๋ฐํํ ์ค์ฒฉ ํจ์์ ๋ฌถ์ฌ์๋ ์์ ๋ณ์๊ฐ ๋์ด ๊ทธ ๊ฐ ์ ์ง
// let ํค์๋๋ฅผ ์ฌ์ฉํด ๋ฌธ์ ํด๊ฒฐ
const funcs = [];
for (let i = 0; i < 3; i++) {
funcs[i] = function () return i
}
for (let i = 0; i < func.length; i++) {
console.log(funcs[i]()); // 0 1 2
}
์ ์์ ์์
for
๋ฌธ์ ํจ์์ ์์ ์ค์ฝํ๋for
๋ฌธ์ ์ฝ๋ ๋ธ๋ก์ด ๋ฐ๋ณต ์คํ๋ ๋๋ง๋ค ์์ฑ๋for
๋ฌธ ์ฝ๋ ๋ธ๋ก์ ์๋ก์ด ๋ ์์ปฌ ํ๊ฒฝ์ด๋ค.
let
ํค์๋๋ ๋ธ๋ก ๋ ๋ฒจ ์ค์ฝํ์ด๊ธฐ ๋๋ฌธ์for
๋ฌธ์ด ๋ฐ๋ณต๋ ๋๋ง๋ค ์๋ก์ด ๋ ์์ปฌ ํ๊ฒฝ์ ์์ฑํ๋ค.
๋ฐ๋ณต๋ฌธ์ ์ฝ๋ ๋ธ๋ก ๋ด๋ถ์์ ํจ์๋ฅผ ์ ์ํ ๋ ์๋ฏธ๊ฐ ์๋ค. ์๋ก์ด ๋ ์์ปฌ ํ๊ฒฝ์ ์๋ฌด๋ ์ฐธ์กฐํ์ง ์๊ธฐ ๋๋ฌธ์ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ ๋์ฐ์ด ๋๋ค.
๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ๊ธฐ๋ฒ์ธ ๊ณ ์ฐจ ํจ์๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
// ์์๊ฐ 3๊ฐ์ธ ๋ฐฐ์ด์ ์์ฑํ๊ณ ๋ฐฐ์ด์ ์ธ๋ฑ์ค๋ฅผ ๋ฐํํ๋ ํจ์๋ฅผ ์์๋ก ์ถ๊ฐํ๋ค.
// ๋ฐฐ์ด์ ์์๋ก ์ถ๊ฐ๋ ํจ์๋ค์ ๋ชจ๋ ํด๋ก์ ๋ค.
const funcs = Array.from(new Array(3), (_, i) => () i); // (3) [f, f, f]
// ๋ฐฐ์ด์ ์์๋ก ์ถ๊ฐ๋ ํจ์๋ค์ ์์ฐจ์ ์ผ๋ก ํธ์ถํ๋ค.
funcs.forEach(f => console.log(f())); // 0 1 2