[내가 이해하는 자바스크립트] var, let, const, 그리고 호이스팅

1q2w3e4r·2021년 9월 5일
0

함수 스코프

함수에 의해 생기는 유효 범위

블록 스코프

블럭에 의해 생기는 유효 범위 => {}
ex) {}, if문, for문, while문, switch문

var

  • 함수 스코프를 가진다.
// var는 function-scope이기 때문에 for문이 끝난다음에 i를 호출하면 값이 출력이 잘 된다.
// 이건 var가 hoisting이 되었기 때문이다.
for(var j=0; j<10; j++) {
  console.log('j', j)
}
console.log('after loop j is ', j) // after loop j is 10
-----------
다음과 같다.
-----------
var j; 
for(j=0; j<10; j++) {
  console.log('j', j)
}
console.log('after loop j is ', j) // after loop j is 10

// 아래의 경우에는 에러가 발생한다.
function counter () {
  for(var i=0; i<10; i++) {
    console.log('i', i)
  }
}
counter()
console.log('after loop i is', i) // ReferenceError: i is not defined

이 현상을 해결하기 위해선 IIFE (즉시 실행 함수) 형태로 바꿔주면 된다

// IIFE를 사용하면
// i is not defined가 뜬다.
(function() {
  // var 변수는 여기까지 hoisting이 된다.
  for(var i=0; i<10; i++) {
    console.log('i', i)
  }
})()
console.log('after loop i is', i) // ReferenceError: i is not defined

// 이 코드를 실행하면 에러없이 after loop i is 10이 호출된다.
(function() {
  for(i=0; i<10; i++) {
    console.log('i', i)
  }
})()
console.log('after loop i is', i) // after loop i is 10
  • 재선언이 가능하다
	var i = 10;
	var i = 20;

let

  • 블록 스코프를 가짐
  • 변수 재선언이 불가능하다.
  • ES6부터 추가되었다.
function hasValue (p) {
    console.log(v); // ReferenceError: v is not defined
    if(p){
        let v = 'blue'
        console.log(v) 
    }else{
        let v = 'red'
        console.log(v)
    }
    console.log(v); // v is not defined
}
hasValue(10)

const

  • 블록 스코프를 가짐
  • 재선언, 재할당이 불가능하다.
  • 선언과 동시에 초기화를 해야한다.
  • 단 const로 선언한 값이 객체나 배열이면 수정이 가능하다.
const obj = {a: 1, b: 2};
obj.a = 3;
console.log(obj.a); // 3

호이스팅

변수 선언의 끌어올림.
프로그램에서 변수가 중간에서 선언되더라도 변수가 프로그램 첫 머리에 선언되는 것처럼 다른 문장앞에서 생성하는 것을 호이스팅이라고 한다.

기존 var의 호이스팅

변수 선언만 위로 끌어올리고 undefined를 할당했다.

(function() {
  var a = 10;
  (function() {
    console.log(a); // undefined
    var a = 20;
  })();
  console.log(a); // 20
})();
console.log(a); // ReferenceError: a is not defined, 함수 스코프이므로 외부에선 not defined

let, const의 호이스팅

  • TDZ(Temporal Dead Zone, 임시 사각지대)
    const, let에 대해서 실제로 변수가 선언된 위치가 오기전에 해당 변수를 호출할 수 없다.
if(true){
    let a = 10
    if(true){
        // ReferenceError: Cannot access 'a' before initialization
        console.log(a); // 호이스팅은 하되 값을 할당하지 않음.
        const a = 20; // console 전에 선언하면 가능
    }
    console.log(a); // let a
}
console.log(a); // not defined

전역객체의 프로퍼티

var

var c = 30
console.log(window.c) // 30
console.log(c) // 30
delete c // var로 선언된 c는 전역변수 이자 전역객체이기 때문에 삭제할 수 없어 false
console.log(window.c) // 30
console.log(c) // 30

전역변수 범위에서 var 변수 선언시 전역객체의 프로퍼티와 전역변수로 선언이 된다.

let, const

let b = 10 // const 도 동일
console.log(window.b) // undefined
console.log(b) // 10
delete b // false b는 전역객체의 프로퍼티가 아니므로 삭제 안됨.
참고 블로그

블로그1

0개의 댓글

관련 채용 정보