티스토리 뷰

hoising, scope, var

자바스크립트는 C언어 처럼 자료형, 타입에 대한 구분이 명확하지 않다.

var x = 1 , var x = 'hello' 이 두개의 코드가 모두 가능하다.

var x = 1
console.log(x)

이 코드의 결과는 어떠할까? 너무 당연하게 1 일 것이다.

그렇다면,

console.log(x)
var x = 1

이 코드는 어떠할까? 당연히 에러가 나야할까? 그렇지 않다. 결과는 undefined 이다.

분명 console.log(x) 전에 x에 대한 선언이 없음에도 오류가 나지 않는다.

그 이유는 var의 hoisting 이라는 특성 때문이다.

hoisting이란 var에 대한 선언을 해당 scope의 맨 위로 끌어 올리는 것을 의미한다.

즉 위 코드는 아래의 코드와 동일한 의미를 갖는다.

var x
console.log(x)
x = 1

또한 hoisting은 var뿐만 아니라 function에서도 동일하게 발생한다.

console.log(foo())
function foo() {
    return 'foo'
}

위 코드의 경우 foo가 출력이 된다.

다음은 scope에 대해 살펴보자.

function foo(){
    let x = 1
    function bar() {
        console.log(x)
    }
}

위 경우 x 가 bar() 안에서 선언되지 않았지만 그 상위 스코프에서 선언되었기에 bar에서 사용이 가능하다. 만약 그 반대로 bar에서 선언한 변수를 foo에서 사용하는 것은 불가능할 것이다.

이렇게 코드의 식별자가 실제로 어떤 값을 가리키는지 결정하는 것을 바인딩 이라고 한다. 자바스크립트에서의 바인딩은 lexical scope를 통해 이루어지는데 이는 위 예시와 같이 안쪽에서 바깥 쪽 변수에 접근할 수 있다는 의미를 가진다.

var x = 1
if (true){
    var x = 2
}
console.log(x)

위 코드의 결과는 무엇일까? if 라는 scope안에서 x = 2가 되었으므로 결과는 1이 나올까?

아니다 결과는 2 가 나온다. 그 이유는 var이 가지는 특성에 있다.

var은 block scoping의 대상이 아니기 때문이다. 그러나 아래에 설명하는 let과 const는 block scoping이 된다.


let 과 const

let 과 const는 ES6에 추가된 변수 선언 키워드이다.

var과 달리 hoisting 규칙이 없고 block scoping을 지원하기에 var보다 훨씬 예측 가능한 코드를 작성할 수 있게 해준다는 큰 장점이 존재한다.

따라서 이제는 var은 사용되지 않고 let과 const를 사용하게 된다.

let x = 1
x = 2 //OK

let으로 선언한 코드는 나중에 값 변경이 가능하다.

const x = 1
x = 2 // X

반면 const는 처음 선언한 값이 바뀌지 않는다. 말 그대로 상수화 되어 사용하게 된다.

var x = 1
var x = 2 // OK

let x = 1
let x = 2 // X

var과 let의 차이를 살펴보자. var은 똑같은 변수명으로 정의하는 것이 가능하다. 하지만 let의 경우 똑같은 변수명으로 선언할 경우 에러를 뿜게 된다.

또한, 위에서 var은 hoisting에 의해 선언 전에도 해당 변수 사용이 가능하였지만 let과 const는 hoisting 규칙이 없기에 선언 전에 변수 사용이 불가능하다.

코드는 항상 유지보수를 생각하며 작성해야 한다. 그러나 var을 남발하게 되면 정말 예측하기 힘든 코드가 만들어 질것이다.

따라서, var는 아예 사용조차 하려하지 않고 가능한 const를 사용하고, 필요에 한해 let을 사용하는 것이 best-practice 인 것 같다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함