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 |