이번 포스팅에서는 전역변수와 지역변수의 개념에 대해 알아보고자 한다.
전역변수(global variable)는 함수 바깥에서 선언된 변수를 얘기하며 프로그램 전체에서 접근이 가능한 변수이다. 이와 다르게 지역변수(local variable)는 함수 내부에서 선언된 변수로 함수의 실행, 종료와 함께 생성되고 소멸되는 변수이다. 지역변수는 함수 바깥쪽에서 접근하는 것이 불가능하다.
아래의 예제 코드를 살펴보면서 전역변수와 지역변수의 차이에 대해 조금 더 이해해보자.
// 1번
let a = 1;
function aa() {
a = 0;
}
aa()
console.log(a) // output : 0
// 2번
let a = 1;
function aa() {
let a = 0;
}
aa()
console.log(a) // output : 1
console.log(a)의 출력 결과를 살펴보면 1번 코드의 결과값은 0이 나오고 2번 코드의 결과값은 1이 나오는 것을 확인할 수 있다. 이러한 차이는 전역에서 변수를 선언했는지, 함수 안에서 변수를 선언했는지의 여부에 따라 결정되게 된다.
1번 코드에서는 함수 aa()가 실행되면서 전역에서 선언된 변수 let a = 1;을 참조해 a 변수에 0이라는 값을 다시 할당해 주게 된다. 그 결과 메모리 힙에 저장되어 있는 변수 a의 값이 0으로 바뀌게 되고 console.log(a)의 결과값이 0으로 출력되는 것이다.
2번 코드의 let a = 0;은 aa() 함수 안에서 변수가 선언된 형태이기 때문에 지역변수가 된다. 그 결과 함수 바깥에 존재하는 코드인 console.log(a)는 aa() 함수 안에 있는 a값에 접근할 수 없게 되고 전역에서 선언된 let a = 1;을 출력하게 되는 것이다.
여기까지의 설명은 위에서 얘기한 전역변수와 지역변수의 개념을 사용해서 진행한 설명이다. 조금 더 나아가서 메모리 공간 개념을 활용해 1번 코드와 2번 코드의 차이를 알아보자.
1번 코드와 2번 코드의 차이는 함수 안에서 let을 사용해 선언을 해줬는지의 여부이다. 2번 코드에서와 같이 변수 앞에 let을 붙여 선언을 해준다는 것은 JavaScript 안의 메모리 공간을 새로 만들어서 사용하겠다는 의미이고 1번 코드와 같이 선언문이 없다는 것은 메모리 공간 안에 존재하고 있는 기존에 선언되었던 변수들을 사용하겠다는 의미이다. 다시말해, 선언문이 있는 변수는 메모리 공간을 새로 만들고 그 안에 변수를 집어넣어 사용하겠다는 의미인 반면 선언문이 없는 변수는 기존에 메모리 공간 안에 있던 변수를 사용하겠다는 의미(기존에 선언되어 있던 변수들 중에서 가져온다는 뜻)인 것이다.
2번 코드의 aa() 함수는 함수 안에서 let a = 0;을 통해 변수 a를 선언해 주었다. 그 결과 aa() 함수가 실행되면 메모리 힙에 저장되어 있던 aa() 함수 자신이 가지고 있는 메모리 공간 안에 a 변수가 새로 생성되어 저장된다. 함수 안에서 선언된 변수는 함수가 차지하고 있는 메모리 공간 안에 저장되어 있기 때문에 console.log(a)는 let a = 0;을 가져오지 못하고 전역에서 선언된 let a = 1;의 값을 가져오게 되는 것이다.
이와 다르게 1번 코드의 function aa() { } 안에 있는 a = 0;은 선언문이 없는 형태이기 때문에 일차적으로 자신이 속한 코드 블록 안에서 a 변수를 찾으려고 할 것이다. 하지만 aa() 함수 안에서는 a 변수가 선언된 적이 없기 때문에 함수 바깥에서 선언된 let a = 1;을 사용해서 a 변수에 0을 할당해주게 된다. 그 결과 console.log(a)의 결과값이 0으로 출력된다.
이제 조금 더 복잡한 다음의 예제코드를 살펴보자.
let a = 1;
function aa() {
let a = 0;
function bb() {
let a = 2;
return a
}
console.log( bb() )
}
aa() // output : 2
console.log(a) // output : 1
let a = 1;에 의해 a 변수가 선언됨과 동시에 1이라는 값이 할당되어 메모리 공간 안에 저장된다. 그 다음에 오는 function aa() 역시 메모리 공간 안에 저장되게 된다. 그리고 aa() 함수가 호출되면서 function aa() 함수 안에 있는 코드들이 실행된다. 이 때 function aa() 안에 있는 let a = 0;이 선언되고 function bb() 함수가 정의되게 된다. function aa() 안에서 선언된 let a = 0;은 함수 aa()가 차지하고 있는 메모리 공간 안에 저장되며 마찬가지로 function bb() 역시 함수 aa()가 차지하고 있는 메모리 공간 안에 저장된다. function aa() 안에 있는 console.log( bb() ) 가 실행되면서 bb() 함수가 호출되고 return 값인 a 를 출력하게 된다. 이 때 출력되는 a 값은 동일한 원리에 의해 function bb() 함수 안에서 선언된 let a = 2;가 된다. 마지막 줄에 위치한 console.log(a)가 실행 될 때 가져오게 되는 변수는 전역에서 선언된 첫째줄에 위치한 let a = 1;이 되어 1이 출력되게 된다.
'JavaScript' 카테고리의 다른 글
JavaScript - 불변성(Immutability) (2) | 2023.10.23 |
---|---|
JavaScript - 일급 객체(First Class Object) & 일급 함수(First Class Function) (0) | 2023.10.19 |
JavaScript ES6 - 템플릿 리터럴 , 객체 리터럴 , 구조분해 할당 (0) | 2022.01.27 |
JavaScript - DOM (2) (0) | 2022.01.12 |
JavaScript - DOM (1) (0) | 2022.01.10 |