for (var i = 0; i < 10; i++) {
/* ... */
}
console.log(i); // what will this output?
여기서 우리는 undefined나 error가 나오는 것을 추측할 수 있겠지만, 값은 10이 나온다.
대부분의 다른 언어에서는, 위의 코드는 error를 출력할 것이다. 변수 i는 block안에서 제한되어 수명(!)을 다할 것이기 때문이다. 하지만, 자바스크립트에서는 변수 var
가 쓰인 이와 같은경우에 for loop가 완전히 실행된 후에도 마지막 value가 scope안에 남게 된다.
그래서 block level scope에 대한 지원은 ES6의 새로운 let
, const
키워드를 통해 JavaScript에 적용되고 있다.
변수 const 나 let은 block level scope 이기에 선언 이전에 참조할 수 없으며
변수 var는 function level scope이기에 선언 이전에 참조할 수 있다.
function findSmallestElement(arr) {
if (arr.length == 0){
return 0
} else {
let min = arr[0]
for (let i = 1; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
return min;
}
}
숫자로 이루어진 arr 의 값들 중 가장 작은 값을 리턴 해주어 값을 구하는 문제인데, 처음에 기준값으로 잡은 let min = arr[0]을 for loop 안의 block에 넣어 'min is not defined' 값이 출력되는 오류가 생겼다.
for loop안에 넣어버리면 block level scope의 성질에 따라 변수 min의 값에 할당할 arr 함수를 가져올 수 없게 되기 때문이다!
for loop block밖으로 변수를 이동해주어 arr의 값을 받아오게 하니, 깔끔하게 문제가 해결되었다.
const getEven = () => {
let result = [];
for (let i = 1; i <= 50; i++) {
if (i % 2 == 0) {
result.push(i);
}
}
return result;
};
1부터 50까지의 자연수에서 짝수를 구해 배열로 리턴하는 이 문제에서도, 처음 let result의 위치를 for 문이나 if 문 안에 위치해주니 값이 나오지 않았다.
여기서 논리부족과 코드가 복잡해질수록 변수선언이 꼬여버리는 상황을 보며..다시 한 번 개념정리가 필요하다고 느껴서 정리하는 scope!
- What is Scope ? 변수가 선언되고 사용할 수 있는 공간
Global Scope - 자바스크립트 애플리케이션 전역에서 접근할 수 있는 범위
Local Scope - 1. Function Scope,
function 안에서 선언된 scope
-2. Block Scope
Global variable - (함수 밖에서 선언된), 즉 애플리케이션 전체에서 사용할 수 있는 변수
Local variable - (함수 안에서 선언된), 즉 함수 내에서만 유효한 변수
간단하게, 밖에서는 안이 보이지 않고 안에서만 밖을 볼 수 있다!
let globalMessage = 'global'; //global variable
function printMessage(){
let message = 'hello';
console.log(message); //local variable
console.log(globalMessae);
function printAnother(){
console.log(message);
let childMessage = 'hello';
}
console.log(childMessage); //ChildMessage is not defined
}
printMessage();
이렇게 중첩된 함수에서 printMessage 함수 안에 정의된 변수를 printAnother 함수에서도 접근가능하여(Closure) 자식은 부모에게 정의된 메세지값을 가져올 수 있지만, 자식이 가지고 있는 값을 부모에게서 보려고 한다면 보이지 않는다
global 변수를 쓰면 접근하기 쉬워서 좋다고 생각되지만, 남용하게 되면 프로그램에 문제를 일으킬 수 있다.
global 변수가 계속 살아있어서 변수값이 계속 변한다면 해당 변수를 트래킹하기도 어렵고 어디서 let, const 로 선언했는지 찾아야하는 번거로움도 있다. 그래서 이러한 문제를 방지하기 위해,
전역변수보다는 지역변수를 사용하는 것이 권장되고 있다.
global 변수가 여기저기서 수정되면 안되기 때문에, 변수들은 최대한 block scope으로 나눠놔야한다.
tightly coping의 변수는 코드의 품질을 올려주고, 코드가 block으로 명확하게 구분되기 때문에 코드 가독성이 올라간다.
프로그램이 끝날 때까지 변수가 살아있는 것이 아니라서(block이 끝나면 local 변수의 삶이 끝나서) 메모리의 절약도 된다.
즉, global 변수는 쓰지 않도록 노력해야하고, 최대한 {}
내에서 let
, const
을 사용하여 변수를 새로 만들어 쓰는 좋은 scoping 습관을 갖도록 하자. (•̀ᴗ•́)و ̑̑