길/Javascript 기본

scope & closer

7he8oy 2021. 1. 26. 15:00
  let const var
유효 범위 Block Scope Block Scope Function Scope
값 재정의 가능 불가능  가능
재선언 불가능 불가능 가능

Block Scope는

'{  }'를 scope 기준으로 삼는다.

따라서 if, function, for 등 '{}' 안에서 사용되면 그 안에만 적용된다.

 

Fucntion Scope는

함수를 단위로 한다. 

따라서 if, for 문에서 어떤 변수가 정의 된다면,

그 정의된 변수는 밖으로 빠져나온다.

 

 

 

 

전역 변수와 Window 객체

Global Scope에서 선언된 함수, 그리고 var를 이용해 선언된 변수는 window 객체에 들어간다.

window;

 

 

선언 없이 초기화된  변수

변수를 선언없이 초기화하면 

'무조건' window 객체 아래로 들어가고 전역변수가 되어버린다.

따라서 하지말것

 

 


 

Closer

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

 

아래에서 innerFn()을 클로저 함수라고 한다.

이 클로저 함수 안에서는

  • 지역 변수
  • 외부 함수의 변수
  • 전역 변수

이 3가지에 접근이 모두 가능하다.

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

outerFn(); //? 

//아래 값이 출력된다. 즉 innerFn 함수 전체가 출력 됨.
//	function innerFn() {
//  	  	let innerVar = 'inner';
//     	   console.log(innerVar);
//	}
//

outerFn()();  				//outervar, innvervar
let innerFn = outerFn();    //outervar
innerFn(); 					//innervar

 

커링

클로저의 예제로 커링을 들고 왔다.

 

컬링은 함수 하나가 n개의 인자를 받는 대신, n개의 함수를 만들어 각각의 인자를 받게 하는 방법이다.

function adder(x) {
	return function(y){
    	return x+y;
    }
}

adder(2)(3); // 5

이렇게 보면 굳이? 라는 생각이 들지만 큰 강점이 있다.

그것은,,,

function adder(x) {
	return function(y){
    	return x+y;
    }
}

adder(2)(3); // 5

let add100 = adder(100);
add100(2);  // 102
add100(10); // 110

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

위의 코드를 보면,

adder함수에서 x값을 특정값(100이나 5)으로 고정한 후에

y값에 새로운 변수에 할당해서 사용하는 것을 알 수 있다.

 

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>
let divMaker = htmlMaker('div')

위 코드를 통해 outer 함수를 실행하고

inner 함수인 divMaker(content) 안에 content를 입력하여

<div>content</div> 형태를 자동으로 작성하는 방식으로 사용할 수 있게 된다.

따라서

divMaker('baby') ;  // <div>baby</div>가 출력된다.

 

 

클로저 모듈 패턴

클로저 모듈 패턴이란, 

변수를 스코프 안쪽에 가두어 함수 밖으로 노출 시키지 않는 방법이다.

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


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

let counter2 = makeCounter();
counter2.increment();
counter2.decrement();
counter2.increment();
counter2.getValue(); //  0

makeCounter함수는 객체를 리턴하는 것을 볼 수 있다.

이 함수가 리턴하는 객체는 각각 함수를 값으로 가지고 있다.

 

따라서 counter1.increment()와 같은 코드는 makecounter()안에 있는 

객체의 key값을 이용하여 함수를 실행시킨다.

 

이때, 각 함수 안의 privateCounter는 outer scope에 +/-를 하게 된다. (전역변수가 아니라 지역변수)

 

그렇기 때문에,

counter1과 counter2는 독립적으로 연산이 된다.

' > Javascript 기본' 카테고리의 다른 글

연산자 사용시 number/string  (0) 2021.01.26
three dots (...)  (0) 2021.01.26
왜 typeof null은 object일까.  (0) 2021.01.26
mutator method인지 참고하는 사이트  (0) 2021.01.25
primitive type vs. reference type  (0) 2021.01.25