2020. 7. 5. 23:27ㆍJavascript/33가지 개념
스코프(Scope)
자바스크립트에서 스코프는 어떤 변수에 접근할 수 있는지 없는지를 정의한다. 스코프는 크게 전역 스코프, 지역 스코프로 나뉜다.
전역 스코프(Global Scope)
전역 스코프는 모든 함수에 속하지 않고, 블록({})안에도 속하지 않은 가장 바깥에 있는 범위를 말한다. 그리고 전역 스코프에 있는 변수를 우리는 전역 변수라고 한다. 전역 변수를 선언하면 어느 블록이든지 간에 선언된 전역변수를 사용할 수 있다.
const greeting = "Hello!";
function sayHello(){
console.log(greeting);
}
sayHello(); // "Hello!"
지역 스코프(Local Scope)
지역 스코프는 함수, 블록({})과 같이 특정 범위를 가리킨다. 지역 스코프안에 있는 변수를 우리는 지역 변수라고 부른다. 자바스크립트에서는 함수, 블록 두 종류의 스코프 존재한다.
함수 스코프는 함수 범위를 말한다. 함수 스코프 안에서 변수를 선언했을 경우, 함수 안에서만 이 변수에 접근할 수 있다.
function sayHello(){
const greeting = "Hello!";
}
console.log(greeting); // Error: greeting is not defined.
또한 함수 스코프는 각자의 스코프에 접근할 수 없다.
function sayHello(){
const hello = "hello";
console.log(hi);
}
function sayHi(){
const hi = "hi";
console.log(hello);
}
sayHello(); // hi is not defined.
sayHi(); // hello is not defined.
하지만, 함수가 다른 함수에서 만들어진 상황에서, 안쪽함수는 바깥함수의 변수에 접근할 수 있다. 이것을 어휘적 스코프(lexical Scope)라고 한다.
function outerFunction () {
const outer = `I see the outer variable!`;
return function() {
console.log(outer);
}();
}
outerFunction();
블록 스코프는 블록({})안에 있는 범위를 말한다. 블록 스코프 안에서 변수를 선언했을 경우, 블록 안에서만 이 변수에 접근할 수 있다.
{
const greeting = "Hello!";
}
console.log(greeting); // Error: greeting is not defined.
함수 호이스팅(Hoisting)
Hoisting은 끌어올리다라는 사전적 의미를 갖고 있다. 자바스크립트에서 함수는 다음과 같이 표현할 수 있다.
sayHello();
function sayHello(){ // (1)
console.log("Hello");
}
const sayHello = function(){ // (2)
console.log("Hello");
}
(1)과 같이 표현한 함수를 우리는 함수 표현식이라고 부르고, (2)와 같이 선언한 함수를 우리는 함수 선언식이라고 부른다. 위 프로그래밍을 실행하면 결과는 당연히 에러다. 자바스크립트 개발자들은 함수 표현식 보다 함수 선언식을 쓸 것을 권장하고 있다. 그 이유는 다음과 같다.
function sayHello(){ // (1)
console.log("Hello");
}
sayHello();
sayHello();
function sayHello(){ // (2)
console.log("Hello");
}
위 두 프로그램의 결과가 똑같이 Hello를 출력하기 때문이다. 그 이유는 함수 표현식을 이용하면 함수가 호이스팅되기 때문이다. 좀 더 쉽게 말하자면 함수 표현식을 이용하면 코드가 순서대로 실행되지 않고, 호이스팅되어 가장 먼저 실행된다. (2)의 경우를 보면 첫 번째 줄에 있는 sayHello()보다 function sayHello(){ ... } 구문이 먼저 실행된다. 하지만 함수 선언식을 이용하면 에러가 난다.
sayHello();
const sayHello = function(){
console.log("Hello");
}
이런 이유로 개발자들은 함수 선언식을 이용할 것을 권하고 있다. 왜냐하면 항상 함수는 선언 전에 미리 사용해야하기 때문이다.
예약어 Var
변수를 선언할 때 사용하는 예약어 var도 호이스팅된다. 다음 프로그래밍을 보면 알 수 있다.
if(true){
var greeting = "hello";
}
console.log(greeting);
위 코드를 실행하면 에러가 발생하지 않는다. 그 이유는 var greeting 코드가 호이스팅되기 때문이다. 이런 이유로 다음 코드 역시 에러가 나지 않는다.
for(var num = 1; num<=3; num++)
console.log(num);
console.log(num); // 4
또한, var 예약어를 이용해서 똑같은 변수명을 선언해도 오류가 나지 않고 실행된다. 왜냐하면 두 번째 변수가 첫 번째 변수를 덮어쓰기 때문이다. 이는 함수 선언식도 마찬가지다.
var num = 123;
var num = 124;
console.log(num); // 124
sayHello(); // hi
function sayHello(){
console.log("hello");
}
function sayHello(){
console.log("hi");
}
따라서 변수를 선언할 때는 const, let 예약어를 사용하도록 하자.
참고 자료
'Javascript > 33가지 개념' 카테고리의 다른 글
[JS 33가지] 7. Expression vs Statement (0) | 2020.07.07 |
---|---|
[JS 33가지] 5. typeof vs instanceof (0) | 2020.06.30 |
[JS 33가지] 4. 형 변환 (0) | 2020.06.26 |
[JS 33가지 개념] 3. 값(Value) VS 참조(Reference) (0) | 2020.06.25 |
[JS 33가지 개념] 2. Primitive Types (0) | 2020.06.23 |