Closure

feelslikemmmm·2020년 9월 18일
0

javascript

목록 보기
20/37
post-thumbnail

► 다음 코드에서 innerFn 함수에 접근할 수 있는 Scope는 총 몇개인가요?

function outerFn() {
	let outerVar = 'outer';
	console.log(outerVar);
	
	function innerFn() {
		let innerVar = 'inner';
		console.log(innerVar);	
	}
}

let globalVar = 'global';
outerFn();

정답) 3개 globalVar, outerVar, innerVar

► 함수도 리턴할 수 있습니다

//이 경우에 outerFn()의 결과는 무엇일까요

function outerFn() {
	let outerVar = 'outer';
	console.log(outerVar);
	
	function innerFn() {
		let innerVar = 'inner';
		console.log(innerVar);	
	}
	return innerFn;
}

outerFn(); 

정답) 1. outerVar의 값이 콘솔에 찍힌다.
		 2. 아직 실행되지 않은 함수(innerFn)가 리턴 됩니다

// 다음의 경우 각각 콘솔에 어떻게 찍힐까요
outerFn()(); // outer , inner
let innerFn = outerFn(); // outer
innerFn(); // inner

► 클로저: 외부 함수의 변수에 접근할 수 있는 내부 함수 , 또는 이러한 작동 원리를 일컫는 용어

function outerFn() {
	let outerVar = 'outer';
	console.log(outerVar);
	//여기서 innerFn()은 클로저 함수 
	//클로저 함수 안에서는 
	//지역변수(innerVar), 외부 함수의 변수(outerVar), 전역 변수(globalVar) 의 접근이 전부 가능
	function innerFn() {
		let innerVar = 'inner';
		console.log(innerVar);	
	}
	return innerFn;
}
let globalVar = 'global';

► 유용한 클로저 예제

  • 커링 : 함수 하나가 n 개의 인자를 받는 대신, n개의 함수를 만들어 각각 인자를 받게 하는 방법
    function adder(x) {
    	return function(y) {
    		return x + y;
    	}
    }
    adder(2)(3); // 5

    let add100 = adder(100); //x의 값을 고정해놓고 재사용할 수 있다.
    add100(2) // 102
    add100(10) // 110

    let add5 = adder(5)
    add5(2) // 7

  • 외부 함수의 변수가 저장되어 마치 템플릿 함수와 같이 사용 가능하다
function htmlMaker(tag) {
	let startTag = '<' + tag + '>';
	let endTag = '</' + tag + '>';
	return function(content) {
		return startTag + content + endTag;
	}
}

let divMaker = htmlMaker('div');
divMaker('code'); // <div>code<div>
divMaker('states'); // <div>states</div>

let h1Maker = htmlMaker('h1');
h1Maker('headline'); // <h1>Headline</h1>

► 클로저 모듈 패턴 : 변수를 스코프 안쪽에 가두어 함수 밖으로 노출 시키지 않는 방법

function makeCounter() {
	let privateConter = 0;
	
	return {
		increment: function() {
			privateConter++;
		},
		decrement: function() {
			privateCounter--;
		},
		gerValue: function() {
			return privateCouner;
		}
	}
}

let counter1 = makeCounter();
counter1.increment();
counter1.increment();
counter1.getValue(); // 2

let counter2 = makeCounter();

counter2.increment();
counter2.decrement();
counter2.increment();
counter2.getValue(); // 1
profile
꾸준함을 잃지 말자는 모토를 가지고 개발하고 있습니다 :)

0개의 댓글