변수에 접근할 수 있는 유효범위이다.
코드가 어디까지 잘 작동하고 있는지 알아야 하기 위해 사용한다.
let x = 'global';
function foo() {
let y = 'local';
console.log(x);
console.log(y);
}
foo(); // global, local
console.log(x); // global
console.log(y); // Uncaught ReferenceError
ReferenceError
: global에서는 local을 참조할 수 없다는 의미let x = 'global';
function foo() {
x = 'local';
return x;
}
foo(); // local
console.log(x); // local
✔️ local에서 global 함수/변수에 접근하는 것은 가능하다.
✔️ global에서 local 함수/변수에 접근하는 것은 불가능하다.
✔️ Scope는 함수 안에 함수를 넣을 수 있다.
① local scope 안에 변수를 선언해주는 경우
let greeting = 'good morning';
function letsGreet() {
let greeting = 'good night';
console.log(greeting); // 2 good night
}
console.log(greeting); // 1 good morning
letsGreet();
console.log(greeting); // 3 good morning
letsGreet()
가 실행된다고 해도 마지막 전역변수는 영향을 받지 않는다.② local scope 안에 변수를 선언하지 않는 경우
let greeting = 'good morning';
function letsGreet() {
greeting = 'good night';
console.log(greeting); // good night
}
console.log(greeting); // good morning
letsGreet();
console.log(greeting); // good night
for (var i = 0; i < 3; i++) {
console.log(i); // 0, 1, 2
}
console.log(i); // 3
var
로 변수를 선언할 경우 block의 범위를 벗어나더라도 function 내에서 사용이 가능하다.for (let i = 0; i < 3; i++) {
console.log(i); // 0, 1, 2
}
console.log(i); // ReferenceError
let
으로 변수를 선언할 경우 block 내에서만 사용이 가능하다.let
을 사용한다.const
를 사용하는 경우가 많다.var
를 사용할 경우 재선언이 가능하지만, 실제로 코딩할 때 재선언 하는 경우는 버그일 가능성이 높기 때문에 권장되지 않는다.var
키워드를 통해 선언된 변수는 window
객체에 들어간다.function greeting() {
console.log('hello');
}
greeting === window.greeting
var symbol = '8ball';
symbol === window.symbol
'use strict'
)를 사용한다.function outerFn() {
let outerVar = 'outer'; // 외부 함수의 변수
console.log(outerVar);
function innerFn() { ← 클로저 함수
let innerVar = 'inner'; // 지역 변수
console.log(innerVar);
}
return innerFn;
}
let globalVar = 'global'; // 전역 변수
outerFn()(); // outer , inner
let innerFn = outerFn(); // outer
innerFn(); // inner
- 클로저 함수 안에서는 아래 변수의 접근이 전부 가능하다.
✔️ 지역 변수innerVar
✔️ 외부 함수의 변수outerVar
✔️ 전역 변수globalVar
let add = function(x) {
let sum = function(y) { ← 클로저 함수
return x + y;
}
return sum;
}
let foo = add(1);
foo(3);
let total = foo(6); // 7
add
는 x
를 매개변수로 하고 함수 sum
을 반환한다.add
는 매개변수 x
를 통해 전달받은 값을 내부함수 sum
에게 내려준다.total
의 값인 foo(6)
는 add(1)(6)
과 같다. 따라서 total
은 7이다.foo(3)
은 무엇일까? foo(3)
이 실행되면 4가 반환되지만, 이 값은 어떠한 변수에도 할당이 되지 않으므로 total
에 영향을 미치지 않는다.let multiplyBy = function(x) { ← 클로저 사용
return function(y) {
return x * y;
}
}
let divideBy = function() {
return function(y) {
return 10 / y;
}
}
x
에 접근할 수 있기 때문에 multiplyBy
가 클로저를 사용하고 있다.divideBy
는 내부함수에서 접근할 수 있는 외부함수의 매개변수가 없기 때문에 클로저를 사용할 수 없다.function adding(x) { // x 값을 고정해놓고 재사용할 수 있음
return function(y) {
return x + y;
}
}
adding(4)(5); // 9
function makeCounter() {
let privateCounter = 0;
return {
increment: function() {
privateCounter++;
},
decrement: function() {
privateCounter--;
},
getValue: function() {
return privateCounter;
}
}
}
Counter
에 각각 다른 privateCounter
를 다루면서, privateCounter
를 밖으로 노출시키지 않는다.참고한 글
https://poiemaweb.com/js-scope
https://gmlwjd9405.github.io/2019/04/22/javascript-hoisting.html