학습 목표
Scope(범위)
JavaScript의 Scope의 의미와 적용 범위를 이해할 수 있다
JavaScript의 Scope 주요 규칙을 이해할 수 있다
중첩 규칙
block level vs. function level
let, const, var의 차이
전역 변수와 전역 객체의 의미
Closure
Closure의 의미와 Closure가 가지는 Scope Chain을 이해할 수 있다
Closure의 유용하게 쓰이는 몇 가지 코딩 패턴을 이해할 수 있다
매개변수
Parameter의 갯수가 유동적인 함수를 만들 수 있다
ES6에서 사용하는 Rest parameter 및 ES5의 방법인 arguments 키워드를 이용할 수 있다
Default parameter를 사용할 수 있다
객체 지향 JavaScript
객체 지향 프로그래밍의 기본적인 컨셉을 이해할 수 있다
class, instance 등의 용어를 이해할 수 있다
new키워드를 사용해 instance를 생성할 수 있다
ES6 class 키워드를 사용할 수 있다
prototype을 이용해 클래스의 원형을 만드는 방법을 이해할 수 있다
학습 내용
Scope

Scope가 가진 규칙들
Rule.1 : Local scope VS Global scope



Rule.2 : Function Scope VS Block Scope






정리


Rule.3 : 전역 변수와 window 객체



Closure
외부 함수의 변수에 접근할 수 있는 내부 함수
예제.1)

예제.2) 함수도 리턴할 수 있다.
다음 outerFn(); 실행 시 찍히는 값은?
function outerFn() {
let outerVar = 'outer';
console.log(outerVar); //일단 console.log 가 실행되어 outer 가 먼저 찍힘
funtion innerFn() {
let innerVar = 'inner';
console.log(innerVar);
}
return innerFn; // 이걸 리턴하라고 했으니 리턴되기는 하되, 먼가 실행되지 않은 함수 자체가 리턴된다. 윗 행의 innerFn 함수가 실행된 것으로 착각하지 말것. 함수는 누가 불러줘야 실행 되는데, 아직 불러준 명령이 없으니 그냥 함수만 리턴 되는 것.(함수도 리턴 될 수 있다는 예시임)
}
outerFn(); //?
예제.3) 다음의 경우 각각 콘솔에 어떻게 찍힐까?
function outerFn() {
let outerVar = 'outer' ;
console.log(outerVar);
function innerFn() {
let innerVar = 'inner';
console.log(innerVar);
}
return innerFn;
}
outerFn()();
outer : 첫 번째 outerFn()로 인해 outer 가 찍힘
inner : 두 번째 ()가 return innerFn 을 만나 innerFn() 효과가 발휘 되면서, 즉 innerFn 함수를 돌려봐라!는 명령어가 되면서 innerFn함수가 작동 되었고 이로인해 inner가 찍힌다.
let innerFn = outerFn();
outer : innerFn이라는 변수에 outerFn()이 할당되었을 뿐, 결과값은 outerFn()의 결과가 찍히게 된다. 단, innerFn을 변수 선언했기 때문에 innerFn을 콘솔창에 찍어보면, 아래 innerFn의 함수가 들어가 있음을 확인할 수 있다.
Function innerFn() {
let innerVar = 'inner';
console.log(innerVar);
}
innerFn() : inner
Closure 란...?
외부 함수의 변수에 접근할 수 있는 내부 함수
(또는, 이러한 작동 원리를 일컫는 용어)

유용한 closure 함수 예제
function adder(x) {
return function(y) {
return x + y;
}
}
adder(2)(3); // 5 -> 2번 연속 실행함으로써 사용할 수 있는 함수
아래같은 경우에 유용하다
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 privatCounter = 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(); // 1