ํด๋ก์ ์ ์๋ฏธ ๋ฐ ์๋ฆฌ ์ดํด
์์์ ์คํ์ปจํ ์คํธ์ ๋ํด ๋ฐฐ์ด ์ง์์ ๋ฐํ์ผ๋ก ํด๋ก์ ๋ฅผ ์ ์ํด๋ณธ๋ค๋ฉด, ํด๋ก์ ๋ ์ธ๋ถ ํจ์์ ๋ณ์๋ฅผ ์ฐธ์กฐํ๋ ๋ด๋ถ ํจ์๋ฅผ ์ธ๋ถ๋ก ์ ๋ฌํ ๋ ์ธ๋ถ ํจ์์ ์คํ ์ปจํ ์คํธ๊ฐ ์ข ๋ฃ๋ ํ์๋ ์ธ๋ถ ํจ์๋ฅผ ์ฐธ์กฐํ ์ ์๋ ํ์์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ ๊ฐ ์ ํด๋ก์ ๋ฅผ ์ ์ํ๋์ง ์์ ๋ฅผ ํตํด ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์ฐ์ ์ธ๋ถ ํจ์์์ ๋ณ์๋ฅผ ์ ์ธํ๊ณ ๋ด๋ถ ํจ์์์ ํด๋น ๋ณ์๋ฅผ ์ฐธ์กฐํ๋ ํํ์ ๊ฐ๋จํ ์ฝ๋๋ฅผ ์์ฑํด๋ณด๊ฒ ์ต๋๋ค.
var outer = function () {
var a = 1;
var inner = function () {
console.log(++a);
};
inner();
};
outer();
outer ํจ์์์ ๋ณ์ a๋ฅผ ์ ์ธํ๊ณ , outer์ ๋ด๋ถ ํจ์์ธ inner ํจ์์์ a์ ๊ฐ์ 1๋งํผ ์ฆ๊ฐ์ํจ ๋ค์ ์ถ๋ ฅํฉ๋๋ค. inner ํจ์ ๋ด๋ถ์์๋ a๋ฅผ ์ ์ธํ์ง ์์๊ธฐ ๋๋ฌธ์ environmentRecord์์ ๊ฐ์ ์ฐพ์ง ๋ชปํ๋ฏ๋ก outerEnvironmentReference์ ์ง์ ๋ ์์ ์ปจํ ์คํธ์ธ outer์ LexicalEnvironment์ ์ ๊ทผํด์ ๋ค์ a๋ฅผ ์ฐพ์ต๋๋ค. 4๋ฒ์งธ ์ค์์๋ 2๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค. outer ํจ์์ ์คํ ์ปจํ ์คํธ๊ฐ ์ข ๋ฃ๋๋ฉด LexicalEnvironment์ ์ ์ฅ๋ ์๋ณ์(a, inner)์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ง์๋๋ค. ๊ทธ๋ฌ๋ฉด ๊ฐ ์ฃผ์์ ์ ์ฅ๋ผ ์๋ ๊ฐ๋ค์ ์์ ์ ์ฐธ์กฐํ๋ ๋ณ์๊ฐ ํ๋๋ ์๊ฒ ๋๋ฏ๋ก ๊ฐ๋น์ง ์ปฌ๋ ํฐ์ ์์ง ๋์์ด ๋ ๊ฒ์ ๋๋ค.
๋ค๋ฅธ ์์ ๋ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
var outer = function () {
var a = 1;
var inner = function () {
return ++a;
};
return inner();
};
var outer2 = outer();
console.log(outer2);
์ด๋ฒ์๋ inner ํจ์ ๋ด๋ถ์์ ์ธ๋ถ ๋ณ์์ธ a๋ฅผ ์ฌ์ฉํ์ต๋๋ค. ๊ทธ๋ฐ๋ฐ 6๋ฒ์งธ ์ค์์๋ Inner ํจ์๋ฅผ ์คํํ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํดํ๊ณ ์์ผ๋ฏ๋ก ๊ฒฐ๊ณผ์ ์ผ๋ก outer ํจ์์ ์คํ ์ปจํ ์คํธ๊ฐ ์ข ๋ฃ๋ ์์ ์๋ a ๋ณ์๋ฅผ ์ฐธ์กฐํ๋ ๋์์ด ์์ด์ง๋๋ค. ์์ ์์ ์ ๋ง์ฐฌ๊ฐ์ง๋ก a, inner ๋ณ์์ ๊ฐ๋ค์ ์ธ์ ๊ฐ ๊ฐ๋น์ง ์ปฌ๋ ํฐ์ ์ํด ์๋ฉธํ ๊ฒ์ ๋๋ค. ์ญ์ ์ผ๋ฐ์ ์ธ ํจ์ ๋ฐ ๋ด๋ถ ํจ์์์์ ๋์๊ณผ ์ฐจ์ด๊ฐ ์์ต๋๋ค.
์ ๋ outer ํจ์์ ์คํ ์ปจํ ์คํธ๊ฐ ์ข ๋ฃ๋๊ธฐ ์ด์ ์ inner ํจ์์ ์คํ ์ปจํ ์คํธ๊ฐ ์ข ๋ฃ๋ผ ์์ผ๋ฉฐ, ์ดํ ๋ณ๋๋ก inner ํจ์๋ฅผ ํธ์ถํ ์ ์๋ค๋ ๊ณตํต์ ์ด ์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด outer์ ์คํ ์ปจํ ์คํธ๊ฐ ์ข ๋ฃ๋ ํ์๋ inner ํจ์๋ฅผ ํธ์ถํ ์ ์๊ฒ ๋ง๋ค๋ฉด ์ด๋จ๊น์?
var outer = function () {
var a = 1;
var inner = function () {
return ++a;
};
return inner;
};
var outer2 = outer();
console.log(outer2());
console.log(outer2());
์ด๋ฒ์๋ 6๋ฒ์งธ ์ค์์ inner ํจ์์ ์คํ ๊ฒฐ๊ณผ๊ฐ ์๋ inner ํจ์ ์์ฒด๋ฅผ ๋ฐํํ์ต๋๋ค. ๊ทธ๋ฌ๋ฉด outer ํจ์์ ์คํ ์ปจํ ์คํธ๊ฐ ์ข ๋ฃ๋ ๋ outer2 ๋ณ์๋ outer์ ์คํ ๊ฒฐ๊ณผ์ธ inner ํจ์๋ฅผ ์ฐธ์กฐํ๊ฒ ๋ ๊ฒ์ ๋๋ค. ์ดํ 9๋ฒ์งธ์์ outer2๋ฅผ ํธ์ถํ๋ฉด ์์ ๋ฐํ๋ ํจ์์ธ inner๊ฐ ์คํ๋ ๊ฒ์ ๋๋ค.
inner ํจ์์ ์คํ ์ปจํ ์คํธ์ environmentRecord์๋ ์์งํ ์ ๋ณด๊ฐ ์์ต๋๋ค. outer-EnvironmentReference์๋ inner ํจ์๊ฐ ์ ์ธ๋ ์์น์ LexicalEnvironment๊ฐ ์ฐธ์กฐ ๋ณต์ฌ๋ฉ๋๋ค. inner ํจ์๋ outer ํจ์ ๋ด๋ถ์์ ์ ์ธ๋์ผ๋ฏ๋ก, outer ํจ์์ LexicalEnvironment๊ฐ ๋ด๊ธธ ๊ฒ์ ๋๋ค. ์ด์ ์ค์ฝํ ์ฒด์ด๋์ ๋ฐ๋ผ outer์์ ์ ์ธํ ๋ณ์ a์ ์ ๊ทผํด์ 1๋งํผ ์ฆ๊ฐ์ํจ ํ ๊ทธ ๊ฐ์ธ 2๋ฅผ ๋ฐํํ๊ณ , inner ํจ์์ ์คํ ์ปจํ ์คํธ๊ฐ ์ข ๋ฃ๋ฉ๋๋ค. 10๋ฒ์งธ ์ค์์ ๋ค์ outer2๋ฅผ ํธ์ถํ๋ฉด ๊ฐ์ ๋ฐฉ์์ผ๋ก a์ ๊ฐ์ 2์์ 3์ผ๋ก 1 ์ฆ๊ฐ์ํจ ํ 3์ ๋ฐํํฉ๋๋ค.
๊ทธ๋ฐ๋ฐ ์ด์ํ ์ ์ด ์์ต๋๋ค. Inner ํจ์์ ์คํ ์์ ์๋ outer ํจ์๋ ์ด๋ฏธ ์คํ์ด ์ข ๋ฃ๋ ์ํ์ธ๋ฐ outer ํจ์์ LexicalEnvironment์ ์ด๋ป๊ฒ ์ ๊ทผํ ์ ์๋ ๊ฒ์ผ๊น์? ์ด๋ ๊ฐ๋น์ง ์ปฌ๋ ํฐ์ ๋์ ๋ฐฉ์ ๋๋ฌธ์ ๋๋ค. ๊ฐ๋น์ง ์ปฌ๋ ํฐ๋ ์ด๋ค ๊ฐ์ ์ฐธ์กฐํ๋ ๋ณ์๊ฐ ํ๋๋ผ๋ ์๋ค๋ฉด ๊ทธ ๊ฐ์ ์์ง ๋์์ ํฌํจ์ํค์ง ์์ต๋๋ค. ์์ ์์์์ outer ํจ์๋ ์คํ ์ข ๋ฃ ์์ ์ inner ํจ์๋ฅผ ๋ฐํํฉ๋๋ค. ์ธ๋ถ ํจ์์ธ outer์ ์คํ์ด ์ข ๋ฃ๋๋๋ผ๋ ๋ด๋ถ ํจ์์ธ inner ํจ์๋ ์ธ์ ๊ฐ outer2๋ฅผ ์คํํจ์ผ๋ก์จ ํธ์ถ๋ ๊ฐ๋ฅ์ฑ์ด ์ด๋ฆฐ ๊ฒ์ ๋๋ค. ์ธ์ ๊ฐ inner ํจ์์ ์คํ ์ปจํ ์คํธ๊ฐ ํ์ฑํ๋๋ฉด outerEnvironmentReference๊ฐ outer ํจ์์ LexicalEnvironment๋ฅผ ํ์๋ก ํ ๊ฒ์ด๋ฏ๋ก ์์ง ๋์์์ ์ ์ธ๋ฉ๋๋ค. ๊ทธ ๋์ inner ํจ์๊ฐ ์ด ๋ณ์์ ์ ๊ทผํ ์ ์๋ ๊ฒ์ ๋๋ค.
์ด๋ฅผ ํตํด ๋ค์ ์ ๋ฆฌํด๋ณด๋ฉด, ํด๋ก์ ๋ ์ธ๋ถ ํจ์์ ๋ณ์๋ฅผ ์ฐธ์กฐํ๋ ๋ด๋ถ ํจ์๋ฅผ ์ธ๋ถ๋ก ์ ๋ฌํ ๋ ์ธ๋ถ ํจ์์ ์คํ ์ปจํ ์คํธ๊ฐ ์ข ๋ฃ๋ ํ์๋ ์ธ๋ถ ํจ์๋ฅผ ์ฐธ์กฐํ ์ ์๋ ํ์์ด๋ผ๊ณ ๋งํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ ๋ค๋ฉด, ํด๋ก์ ๋ฅผ ํ์ฉํ ๋ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ ์ด๋ป๊ฒ ํด์ผ ํ ๊น์? ์ด์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค.
ํด๋ก์ ์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
ํด๋ก์ ๋ ๋ด๋ถ ํจ์๊ฐ ์ธ๋ถ ํจ์์ ๊ฐ์ ์ฐธ์กฐํด์ผ ํ ๋, ์๋์ ์ผ๋ก ํจ์์ ์ง์ญ๋ณ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋ชจํ๋๋ก ํจ์ผ๋ก์จ ๋ฐ์ํฉ๋๋ค. ๊ทธ๋ ๋ค๋ฉด ํจ์จ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น์? ํด๊ฒฐ์ฑ ์ ์ง์ญ๋ณ์์ ํ์์ฑ์ด ์ฌ๋ผ์ง ์์ ์ ๋๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋ชจํ์ง ์๊ฒ ํด ์ฃผ๋ฉด ๋ฉ๋๋ค. ์ฐธ์กฐ ์นด์ดํธ๋ฅผ 0์ผ๋ก ๋ง๋ค๋ฉด ์ธ์ ๊ฐ GC๊ฐ ์๊ฑฐํด๊ฐ ๊ฒ์ด๊ณ , ์ด๋ ์๋ชจ๋๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ์๋ ๊ฒ์ ๋๋ค. ์ฐธ์กฐ ์นด์ดํธ๋ฅผ 0์ผ๋ก ๋ง๋๋ ๋ฐฉ๋ฒ์? ์๋ณ์์ ์ฐธ์กฐํ์ด ์๋ ๊ธฐ๋ณธํ ๋ฐ์ดํฐ(๋ณดํต null์ด๋ undefined)๋ฅผ ํ ๋นํ๋ฉด ๋ฉ๋๋ค. ๋ค์์ ์ฝ๋์ ๋ฉ๋ชจ๋ฆฌ ํด์ ์ฝ๋๋ฅผ ์ถ๊ฐํ ์ฝ๋์ ๋๋ค.
// (1) return์ ์ํ ํด๋ก์ ์ ๋ฉ๋ชจ๋ฆฌ ํด์
var outer = (function () {
var a = 1;
var inner = function() {
return ++a;
};
return inner;
})();
console.log(outer());
console.log(outer());
outer = null; // outer ์๋ณ์์ inner ํจ์ ์ฐธ์กฐ๋ฅผ ๋์
ํด๋ก์ ํ์ฉ ์ฌ๋ก
์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์์ ์ธ๋ถ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ณ ์ ํ ๋
๋ํ์ ์ธ ์ฝ๋ฐฑ ํจ์ ์ค ํ๋์ธ ์ด๋ฒคํธ ๋ฆฌ์ค๋์ ๊ดํ์ฌ ์์๋ณด๊ฒ ์ต๋๋ค.
var fruits = ['apple', 'banana', 'peach'];
var $ul = document.createElement('ul');
fruits.forEach(function(fruit) {
var $li = document.createElement('li');
$li.innerText = fruit;
$li.addEventListener('click', function(){
alert('your choice is ' + fruit);
});
$ul.appendChild($li);
});
document.body.appendChild($ul);
fruits ๋ณ์๋ฅผ ์ํํ๋ฉฐ li๋ฅผ ์์ฑํ๊ณ , ๊ฐ li๋ฅผ ํด๋ฆญํ๋ฉด ํด๋น ๋ฆฌ์ค๋์ ๊ธฐ์ต๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ์คํํ๊ฒ ํ์ต๋๋ค. 4๋ฒ์งธ ์ค์ forEach ๋ฉ์๋์ ๋๊ฒจ์ค ์ต๋ช ์ ์ฝ๋ฐฑ ํจ์(A)๋ ๊ทธ ๋ด๋ถ์์ ์ธ๋ถ ๋ณ์๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์์ผ๋ฏ๋ก ํด๋ก์ ๊ฐ ์์ง๋ง, 7๋ฒ์งธ ์ค์ addEventListener์ ๋๊ฒจ์ค ์ฝ๋ฐฑ ํจ์(B)์๋ fruit์ด๋ผ๋ ์ธ๋ถ ๋ณ์๋ฅผ ์ฐธ์กฐํ๊ณ ์์ผ๋ฏ๋ก ํด๋ก์ ๊ฐ ์์ต๋๋ค. (A)๋ fruits์ ๊ฐ์๋งํผ ์คํ๋๋ฉฐ, ๊ทธ๋๋ง๋ค ์๋ก์ด ์คํ ์ปจํ ์คํธ๊ฐ ํ์ฑํ๋ ๊ฒ์ ๋๋ค. A์ ์คํ ์ข ๋ฃ ์ฌ๋ถ์ ๋ฌด๊ดํ๊ฒ ํด๋ฆญ ์ด๋ฒคํธ์ ์ํด ๊ฐ ์ปจํ ์คํธ์ (B)๊ฐ ์คํ๋ ๋๋ (B)์ outerEnvironmentReference๊ฐ (A)์ LexicalEnvironment๋ฅผ ์ฐธ์กฐํ๊ฒ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ต์ํ (B) ํจ์๊ฐ ์ฐธ์กฐํ ์์ ์ธ ๋ณ์ fruit์ ๋ํด์๋ (A)๊ฐ ์ข ๋ฃ๋ ํ์๋ GC ๋์์์ ์ ์ธ๋์ด ๊ณ์ ์ฐธ์กฐ ๊ฐ๋ฅํ ๊ฒ์ ๋๋ค.
๊ทธ๋ฐ๋ฐ (B) ํจ์๊ฐ ์ฝ๋ฐฑ ํจ์๋ฟ ์๋๋ผ ๋ค๋ฅธ ๊ณณ์์๋ ์ฐ์ธ๋ค๋ฉด, ๋ฐ๋ณต์ ์ค์ด๊ธฐ ์ํด (B)๋ฅผ ์ธ๋ถ๋ก ๋ถ๋ฆฌํ๋ ํธ์ด ๋์ ์ ์์ ๊ฒ์ ๋๋ค. Bํจ์๋ฅผ ์ธ๋ถ์์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด๋ณด๊ฒ ์ต๋๋ค.
var alertFruit = function(fruit){
alert('your choice is ' + fruit);
};
fruits.forEach(function(fruit) {
var $li = document.createElement('li');
$li.innerText = fruit;
$li.addEventListener('click', alertFruit);
$ul.appendChild($li);
});
document.body.appendChild($ul);
alertFruit(fruits[1]);
์์ ์์์์๋ ๊ณตํต ํจ์๋ก ์ฐ๊ณ ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ธ๋ถ๋ก ๊บผ๋ด์ด alertFruit๋ผ๋ ๋ณ์์ ๋ด์์ต๋๋ค. ์ด์ alertFruit์ ์ง์ ์คํํ ์ ์์ต๋๋ค. ๋ํ 14๋ฒ์งธ ์ค์์๋ ์ ์์ ์ผ๋ก 'banana'์ ๋ํ ์ผ๋ฟ์ด ์คํ๋ฉ๋๋ค.
๊ทธ๋ฐ๋ฐ ๊ฐ li๋ฅผ ํด๋ฆญํ๋ฉด ํด๋ฆญํ ๋์์ ๊ณผ์ผ๋ช ์ด ์๋ [object MouseEvent]๋ผ๋ ๊ฐ์ด ์ถ๋ ฅ๋ฉ๋๋ค. ์ฝ๋ฐฑ ํจ์์ ์ธ์์ ๋ํ ์ ์ด๊ถ์ addEventListener๊ฐ ๊ฐ์ง ์ํ์ด๋ฉฐ, addEventListener๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ํธ์ถํ ๋ ์ฒซ ๋ฒ์งธ ์ธ์์ '์ด๋ฒคํธ ๊ฐ์ฒด'๋ฅผ ์ฃผ์ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ด ๋ฌธ์ ๋ bind ๋ฉ์๋๋ฅผ ํ์ฉํ๋ฉด ์์ฝ๊ฒ ํด๊ฒฐํ ์ ์์ต๋๋ค.
var alertFruit = function(fruit){
alert('your choice is ' + fruit);
};
fruits.forEach(function(fruit) {
var $li = document.createElement('li');
$li.innerText = fruit;
$li.addEventListener('click', alertFruit.bind(null, fruit));
$ul.appendChild($li);
});
document.body.appendChild($ul);
alertFruit(fruits[1]);
๋ค๋ง ์ด๋ ๊ฒ ํ๋ฉด ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์ธ์๋ก ๋์ด์ค๋ ์์๊ฐ ๋ฐ๋๋ ์ ๋ฐ ํจ์ ๋ด๋ถ์์์ this๊ฐ ์๋์ ๊ทธ๊ฒ๊ณผ ๋ฌ๋ผ์ง๋ ์ ์ ๊ฐ์ํด์ผ ํฉ๋๋ค. ์ด๋ฐ ๋ณ๊ฒฝ์ฌํญ์ด ๋ฐ์ํ์ง ์๊ฒ๋ ํ๋ฉด์ ์ด์๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ bind ๋ฉ์๋๊ฐ ์๋ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ํ์ด๋ด์ผ๋ง ํฉ๋๋ค. ์ฌ๊ธฐ์ ๋ค๋ฅธ ๋ฐฉ์์ด๋ ๊ณ ์ฐจ ํจ์๋ฅผ ํ์ฉํ๋ ๊ฒ์ผ๋ก, ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์์ ์์ฃผ ์ฐ์ด๋ ๋ฐฉ์์ด๊ธฐ๋ ํฉ๋๋ค.
var alertFruitBuilder = function (fruit){
return function() {
alert('your choice is ' + fruit);
}
}
fruits.forEach(function (fruit) {
var $li = document.createElement('li');
$li.innerText = fruit;
$li.addEventListener('click', alertFruitBuilder(fruit));
$ul.appendChild($li);
});
4๋ฒ์งธ ์ค์์ alertFruit ํจ์ ๋์ alertFruitBuilder๋ผ๋ ์ด๋ฆ์ ํจ์๋ฅผ ์์ฑํ์ต๋๋ค. ์ด ํจ์ ๋ด๋ถ์์๋ ๋ค์ ์ต๋ช ํจ์๋ฅผ ๋ฐํํ๋๋ฐ, ์ด ์ต๋ช ํจ์๊ฐ ๋ฐ๋ก ๊ธฐ์กด์ alertFruit ํจ์์ ๋๋ค. 12๋ฒ์งธ ์ค์์๋ alertFruitBuilder ํจ์๋ฅผ ์คํํ๋ฉด์ fruit ๊ฐ์ ์ธ์๋ก ์ ๋ฌํ์ต๋๋ค. ๊ทธ๋ฌ๋ฉด ์ด ํจ์์ ์คํ ๊ฒฐ๊ณผ๊ฐ ๋ค์ ํจ์๊ฐ ๋๋ฉฐ, ์ด๋ ๊ฒ ๋ฐํ๋ ํจ์๋ฅผ ๋ฆฌ์ค๋์ ์ฝ๋ฐฑ ํจ์๋ก์จ ์ ๋ฌํ ๊ฒ์ ๋๋ค. ์ดํ ์ธ์ ๊ฐ ํด๋ฆญ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ๋น๋ก์ ์ด ํจ์์ ์คํ ์ปจํ ์คํธ๊ฐ ์ด๋ฆฌ๋ฉด์ alertFruitBuilder์ ์ธ์๋ก ๋์ด์จ fruit๋ฅผ outerEnvironmentReference์ ์ํด ์ฐธ์กฐํ ์ ์์ต๋๋ค. ์ฆ, alertFruitBuilder์ ์คํ ๊ฒฐ๊ณผ๋ก ๋ฐํ๋ ํจ์์๋ ํด๋ก์ ๊ฐ ์กด์ฌํฉ๋๋ค.
์ง๊ธ๊น์ง ์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์์ ์ธ๋ถ ๋ณ์๋ฅผ ์ฐธ์กฐํ๊ธฐ ์ํ ๋ฐฉ๋ฒ ์ธ ๊ฐ์ง๋ฅผ ์ดํด๋ดค์ต๋๋ค.
- ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ด๋ถ ํจ์๋ก ์ ์ธํด์ ์ธ๋ถ ๋ณ์๋ฅผ ์ง์ ์ฐธ์กฐํ๋ ๋ฐฉ๋ฒ์ผ๋ก, ํด๋ก์ ๋ฅผ ์ฌ์ฉํ ๋ฐฉ๋ฒ.
- bind ๋ฉ์๋๋ก ๊ฐ์ ์ง์ ๋๊ฒจ์ค ๋๋ถ์ ํด๋ก์ ๋ ๋ฐ์ํ์ง ์๊ฒ ๋ ๋ฐ๋ฉด ์ฌ๋ฌ ๊ฐ์ง ์ ์ฝ์ฌํญ์ด ๋ฐ๋ฅด๊ฒ ๋์ต๋๋ค.
- ์ฝ๋ฐฑ ํจ์๋ฅผ ๊ณ ์ฐจ ํจ์๋ก ๋ฐ๊ฟ์ ํด๋ก์ ๋ฅผ ์ ๊ทน์ ์ผ๋ก ํ์ฉํ ๋ฐฉ๋ฒ
์ด ์ธ ๋ฐฉ๋ฒ์ ์ฅ๋จ์ ์ ๊ฐ๊ธฐ ํ์ ํ๊ณ ๊ตฌ์ฒด์ ์ธ ์ํฉ์ ๋ฐ๋ผ ์ด๋ค ๋ฐฉ๋ฒ์ ๋์ ํ๋ ๊ฒ์ด ๊ฐ์ฅ ํจ๊ณผ์ ์ผ์ง ๊ณ ๋ฏผํด์ผ ํฉ๋๋ค.
์ ๊ทผ ๊ถํ ์ ์ด (์ ๋ณด ์๋)
๋ ๋ฒ์งธ ์ ๋ณด ์๋์ ์ด๋ค ๋ชจ๋์ ๋ด๋ถ ๋ก์ง์ ๋ํด ์ธ๋ถ๋ก์ ๋ ธ์ถ์ ์ต์ํํด์ ๋ชจ๋ ๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๊ณ ์ ์ฐ์ฑ์ ๋์ด๊ณ ์ ํ๋ ํ๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ์ค์ํ ๊ฐ๋ ์ค ํ๋์ ๋๋ค. ํํ ์ ๊ทผ ๊ถํ์๋ public, private, protected์ ์ธ ์ข ๋ฅ๊ฐ ์์ต๋๋ค. ๊ฐ ๋จ์ด์ ์๋ฏธ ๊ทธ๋๋ก, public์ ์ธ๋ถ์์ ์ ๊ทผ ๊ฐ๋ฅํ ๊ฒ์ด๊ณ , private์ ๋ด๋ถ์์๋ง ์ฌ์ฉํ๋ฉฐ ์ธ๋ถ์ ๋ ธ์ถ๋์ง ์๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ณ์ ์์ฒด์ ์ด๋ฌํ ์ ๊ทผ ๊ถํ์ ์ง์ ๋ถ์ฌํ๋๋ก ์ค๊ณ๋ผ ์์ง ์์ต๋๋ค. ๊ทธ๋ ๋ค๊ณ ์ ๊ทผ ๊ถํ ์ ์ด๊ฐ ๋ถ๊ฐ๋ฅํ ๊ฒ์ ์๋๋๋ค. ํด๋ก์ ๋ฅผ ์ด์ฉํ๋ฉด ํจ์ ์ฐจ์์์ public ํ ๊ฐ๊ณผ private ํ ๊ฐ์ ๊ตฌ๋ถํ๋ ๊ฒ์ด ๊ฐ๋ฅํฉ๋๋ค. ๋ค์ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
var outer = function () {
var a = 1;
var inner = function() {
return ++a;
}
return inner;
};
var outer2 = outer();
console.log(outer2());
console.log(outer2());
outer ํจ์๋ฅผ ์ข ๋ฃํ ๋ inner ํจ์๋ฅผ ๋ฐํํจ์ผ๋ก์จ outer ํจ์์ ์ง์ญ๋ณ์์ธ a์ ๊ฐ์ ์ธ๋ถ์์๋ ์ฝ์ ์ ์๊ฒ ๋์ต๋๋ค. ์ด์ฒ๋ผ ํด๋ก์ ๋ฅผ ํ์ฉํ๋ฉด ์ธ๋ถ ์ค์ฝํ์์ ํจ์ ๋ด๋ถ์ ๋ณ์๋ค ์ค ์ ํ์ ์ผ๋ก ์ผ๋ถ์ ๋ณ์์ ๋ํ ์ ๊ทผ ๊ถํ์ ๋ถ์ฌํ ์ ์์ต๋๋ค. ๋ฐ๋ก return์ ํ์ฉํด์ ๋ง์ ๋๋ค.
closure๋ผ๋ ์์ด ๋จ์ด๋ ์ฌ์ ์ ์ผ๋ก '๋ซํ์์', ํ์์ฑ, ์๊ฒฐ์ฑ' ์ ๋์ ์๋ฏธ๋ฅผ ๊ฐ์ง๋๋ค. ์ด ํ์์ฑ์ ์ฃผ๋ชฉํด๋ณด๋ฉด ์ ์์ ๋ฅผ ์กฐ๊ธ ๋ค๋ฅด๊ฒ ๋ฐ์๋ค์ผ ์ ์์ต๋๋ค. outer ํจ์๋ ์ธ๋ถ(์ ์ญ ์ค์ฝํ)๋ก๋ถํฐ ์ฒ ์ ํ๊ฒ ๊ฒฉ๋ฆฌ๋ ๋ซํ ๊ณต๊ฐ์ ๋๋ค. ์ธ๋ถ์์๋ ์ธ๋ถ ๊ณต๊ฐ์ ๋ ธ์ถ๋ผ ์๋ outer๋ผ๋ ๋ณ์๋ฅผ ํตํด outer ํจ์๋ฅผ ์คํํ ์๋ ์์ง๋ง, outer ํจ์ ๋ด๋ถ์๋ ์ด๋ ํ ๊ฐ์ ๋ ํ ์ ์์ต๋๋ค. ์ธ๋ถ์์๋ ์ค์ง outer ํจ์๊ฐ return ํ ์ ๋ณด์๋ง ์ ๊ทผํ ์ ์์ต๋๋ค. return ๊ฐ์ด ์ธ๋ถ์ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ์ ์ผํ ์๋จ์ ๋๋ค.
๊ทธ๋ฌ๋๊น ์ธ๋ถ์ ์ ๊ณตํ๊ณ ์ ํ๋ ์ ๋ณด๋ค์ ๋ชจ์์ return ํ๊ณ , ๋ด๋ถ์์๋ง ์ฌ์ฉํ ์ ๋ณด๋ค์ return ํ์ง ์๋ ๊ฒ์ผ๋ก ์ ๊ทผ ๊ถํ ์ ์ด๊ฐ ๊ฐ๋ฅํฉ๋๋ค. return ํ ๋ณ์๋ค์ ๊ณต๊ฐ ๋ฉค๋ฒ๊ฐ ๋๊ณ , ๊ทธ๋ ์ง ์์ ๋ณ์๋ค์ ๋น๊ณต๊ฐ ๋ฉค๋ฒ๊ฐ ๋ฉ๋๋ค.
์ง๊ธ๊น์ง ํด๋ก์ ์ ๊ฐ๋ ์ ํ์ฉํด์ ์ธ๋ถ ์ค์ฝํ์์ ํจ์ ๋ด๋ถ์ ๋ณ์ ์ค ์ผ๋ถ์ ์ ๊ทผํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ตํ๋ดค๋๋ฐ, ์ด๋ฒ์๋ ํด๋ก์ ๋ฅผ ํตํด ์ ๊ทผํ๋ ๊ฒ์ด ์๋, getter์ setter ๊ฐ๋ ์ ํตํด ์ ๊ทผํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค.
์ ๊ทผ์ ํ๋กํผํฐ
์ ๊ทผ์๋ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์์ ๊ฐ์ฒด๊ฐ ๊ฐ์ง ํ๋กํผํฐ ๊ฐ์ ๊ฐ์ฒด ๋ฐ๊นฅ์์ ์ฝ๊ฑฐ๋ ์ธ ์ ์๋๋ก ์ ๊ณตํ๋ ๋ฉ์๋๋ฅผ ๋งํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ ๊ทผ์ ํ๋กํผํฐ๋ ๊ฐ์ ํ๋(get)ํ๊ณ ์ค์ (set)ํ๋ ์ญํ ์ ๋ด๋นํฉ๋๋ค. ์ธ๋ถ ์ฝ๋์์๋ ํจ์๊ฐ ์๋ ์ผ๋ฐ์ ์ธ ํ๋กํผํฐ์ฒ๋ผ ๋ณด์ ๋๋ค.
getter์ setter
์ ๊ทผ์ ํ๋กํผํฐ๋ 'getter(ํ๋์)'์ 'setter(์ค์ ์)' ๋ฉ์๋๋ก ํํ๋ฉ๋๋ค. ๊ฐ์ฒด ๋ฆฌํฐ๋ด ์์์ getter์ setter ๋ฉ์๋๋ get๊ณผ set์ผ๋ก ๋ํ๋ผ ์ ์์ต๋๋ค.
let obj = {
get propName() {
// getter, obj.propName์ ์คํํ ๋ ์คํ๋๋ ์ฝ๋
},
set propName(value) {
// setter, obj.propNAme = value๋ฅผ ์คํํ ๋ ์คํ๋๋ ์ฝ๋
}
};
getter ๋ฉ์๋๋ obj.propName์ ์ฌ์ฉํด ํ๋กํผํฐ๋ฅผ ์ฝ์ผ๋ ค๊ณ ํ ๋ ์คํ๋ฉ๋๋ค. setter ๋ฉ์๋๋ obj.propName = value์ผ๋ก ํ๋กํผํฐ์ ๊ฐ์ ํ ๋นํ๋ ค ํ ๋ ์คํ๋ฉ๋๋ค. ์๋ฅผ ํตํด getter์ setter์ ๋ํด ์ดํด๋ณด๊ฒ ์ต๋๋ค.
let user = {
name: "John",
surname: "Smith",
get fullName() {
return `${this.name} ${this.surname}`;
}
};
alert(user.fullName); // John Smith
๋ฐ๊นฅ ์ฝ๋์์ ์ ๊ทผ์ ํ๋กํผํฐ๋ฅผ ์ผ๋ฐ ํ๋กํผํฐ์ฒ๋ผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ ๊ทผ์ ํ๋กํผํฐ๋ ์ด๋ฐ ์์ด๋์ด์์ ์ถ๋ฐํ์ต๋๋ค. ์ ๊ทผ์ ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ํจ์์ฒ๋ผ ํธ์ถํ์ง ์๊ณ , ์ผ๋ฐ ํ๋กํผํฐ์์ ๊ฐ์ ์ ๊ทผํ๋ ๊ฒ์ฒ๋ผ ํ๋ฒํ๊ฒ user.fullName์ ์ฌ์ฉํด ํ๋กํผํฐ ๊ฐ์ ์ป์ ์ ์์ต๋๋ค. ๋๋จธ์ง ์์ ์ getter ๋ฉ์๋๊ฐ ๋ท๋จ์์ ์ฒ๋ฆฌํด์ค๋๋ค. ํํธ ์ ์์์ fullName์ getter ๋ฉ์๋๋ง ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ user.fullName = ์ ์ฌ์ฉํด ๊ฐ์ ์ฌ์ฉํด ๊ฐ์ ํ ๋นํ๋ ค๊ณ ํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
let user = {
name: "John",
surname: "Smith",
get fullName() {
return `${this.name} ${this.surname}`;
}
};
user.fullName = "Test"; // Error (ํ๋กํผํฐ์ getter ๋ฉ์๋๋ง ์์ด์ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.)
ํ์ง๋ง setter๋ฉ์๋๊ฐ ์๋ค๋ฉด, ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค.
let user = {
name: "John",
surname: "Smith",
get fullName() {
return `${this.name} ${this.surname}`;
},
set fullName(value) {
[this.name, this.surname] = value.split(" ");
}
};
// ์ฃผ์ด์ง ๊ฐ์ ์ฌ์ฉํด set fullName์ด ์คํ๋ฉ๋๋ค.
user.fullName = "Alice Special"
alert(user.fullName); // Alice Special
alert(user.name); // Alice
alert(user.surname); // Special
์ด๋ ๊ฒ getter์ setter ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ฉด ๊ฐ์ฒด์ fullName์ด๋ผ๋ '๊ฐ์'์ ํ๋กํผํฐ๊ฐ ์๊น๋๋ค. ๊ฐ์์ ํ๋กํผํฐ๋ ์ฝ๊ณ ์ธ ์ ์์ง๋ง ์ค์ ๋ก๋ ์กด์ฌํ์ง ์์ต๋๋ค. ๊ทธ๋ผ getter์ setter์ ์ฌ์ฉ์ ๋ํด ์กฐ๊ธ ๋ ์์ธํ๊ฒ ์์๋ณด๊ฒ ์ต๋๋ค.
getter์ setter ๋๋ํ๊ฒ ํ์ฉํ๊ธฐ
์ผ๋ฐ์ ์ผ๋ก ์ด๋ฆ์ ์ฝ๊ณ ์์ ํ๋ ๊ฐ์ฒด๋ ๋ค์๊ณผ ๊ฐ์ด ์ด๋ฆ์ ์์ ํ๋ ๋ฉ์๋ setName()์ ํฌํจํ๊ณ ์์ต๋๋ค.
let user = {
name: '',
setName(value) {
if (value.length < 4) {
alert("์
๋ ฅํ์ ๊ฐ์ด ๋๋ฌด ์งง์ต๋๋ค. ๋ค ๊ธ์ ์ด์์ผ๋ก ๊ตฌ์ฑ๋ ์ด๋ฆ์ ์
๋ ฅํ์ธ์.");
return;
}
this.name = value;
}
};
user.setName("Pete");
alert(user.name); // Pete
user.setName(""); // ๋๋ฌด ์งง์ ์ด๋ฆ์ ํ ๋นํ๋ ค ํจ
๊ทธ๋ฌ๋ getter์ setter๋ฅผ '์ค์ ' ํ๋กํผํฐ ๊ฐ์ ๊ฐ์ธ๋ ๋ํผ(wrapper)์ฒ๋ผ ์ฌ์ฉํ๋ฉด, ๋ฉ์๋๋ฅผ ์๋ก ๋ง๋๋ ์ผ ์์ด ํ๋กํผํฐ ๊ฐ์ ์ํ๋ ๋๋ก ํต์ ํ ์ ์์ต๋๋ค.
let user = {
get name() {
return this._name;
},
set name(value) {
if (value.length < 4) {
alert("์
๋ ฅํ์ ๊ฐ์ด ๋๋ฌด ์งง์ต๋๋ค. ๋ค ๊ธ์ ์ด์์ผ๋ก ๊ตฌ์ฑ๋ ์ด๋ฆ์ ์
๋ ฅํ์ธ์.");
return;
}
this._name = value;
}
};
user.name = "Pete";
alert(user.name); // Pete
user.name = ""; // ๋๋ฌด ์งง์ ์ด๋ฆ์ ํ ๋นํ๋ ค ํจ
user์ ์ด๋ฆ์ _name์ ์ ์ฅ๋๊ณ , ํ๋กํผํฐ์ ์ ๊ทผํ๋ ๊ฒ์ getter(user.name)์ setter(user.name = value)๋ฅผ ํตํด ์ด๋ค์ง๋๋ค. ๊ธฐ์ ์ ์ผ๋ก ์ธ๋ถ ์ฝ๋์์ user._name์ ์ฌ์ฉํด ์ด๋ฆ์ ๋ฐ๋ก ์ ๊ทผํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ฐ์ค(user._name)๋ก ์์ํ๋ ํ๋กํผํฐ๋ ๊ฐ์ฒด ๋ด๋ถ์์๋ง ํ์ฉํ๊ณ , ์ธ๋ถ์์๋ ๊ฑด๋๋ฆฌ์ง ์๋ ๊ฒ์ด ๊ด์ต์ ๋๋ค. ์์ ์์ ์์ user.name์ ํตํด ํ๋กํผํฐ์ ์ ๊ทผํ๊ณ ์์ ํ๋ ๊ฒ์ฒ๋ผ user._name์ ์ง์ ์ ์ผ๋ก ์ฌ์ฉํ์ง๋ ์๋ ๊ฒ์ด ์ข์ต๋๋ค.
Reference
'๐ฅ Front-End > JavaScript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[JS] TDZ (0) | 2022.07.21 |
---|---|
[JS] ์คํ ์ปจํ ์คํธ, ํธ์ด์คํ , ํจ์ ์ ์ธ๋ฌธ๊ณผ ํจ์ ํํ์ (0) | 2022.07.21 |
[JS] ์ค์ฝํ(Scope) (0) | 2022.07.21 |
[JS] JavaScript ๊ฐ์ฒด์ ๋ถ๋ณ์ฑ (0) | 2022.07.20 |
[JS] JavaScript์ ์๋ฃํ๊ณผ JavaScript๋ง์ ํน์ฑ (0) | 2022.07.19 |