JS - Block Scope

7956 단어 TILJavaScriptES6ES6

Block Scope

ES5까지 변수로써 사용할 수 있는 키워드는 var가 유일했고 이는 함수를 유일한 블록 스코프(block Scope)로 사용한다는 문제상수 변수를 언어차원에서 제공하지 않는다는 문제를 가지고 있었다.
이를 해결하기 위해, ES6에서는 var를 대신하는 letconst가 등장했다. const라는 상수 변수가 추가되었고 이들은 모두 if문, for문, while문, switch-case문과 같은 문({})을 추가적인 block scope로 간주한다.

예시

/*** let, const ***/
if (true) {
  let a = 10;
  if (true) {
    console.log(a);	// undefined ----------------- 1번
    const a = 20;
  }
  console.log(a);	// 10
}

/****** var ******/
if (true) {
  var a = 10;	
  if (true) {
    console.log(a);	// 10
    var a = 20;
  }
  console.log(a);	// 20
}

위의 예시를 보면 한가지 의문이 생길 수 있다. 문({})block scope로 간주한다는 것은 이해했는데 '1번 시점에 자신의 스코프에 값이 존재하지 않으니까 외부 스코프에서 값을 찾아서 10을 출력해야되는 것 아닌가?' 라는 의문 말이다.
이에 대한 답은 TDZ라는 개념에 있다. 먼저 TDZTemporal Dead Zone의 약자이자 직역하면 임시 사망 지역, 임시 사각 지대 정도의 의미를 가진 추상적인 개념이다. 이는 내부적으로 해당 스코프의 선언들만을 hoisting 해서 외부 참조를 막고 undefined를 반환하도록 만든다. 이 때문에 1번 시점에서 const a라는 선언 부분이 해당 스코프의 상단으로 hoisting 되어 a를 외부에서 참조를 하지 못하고 undefined를 출력하는 것이다.

참고로 TDZ라는 용어는 ECMA Script에 공식적으로 명세되어 있는 개념이 아닌 개발자들 사이에서 암묵적으로 통용되는 용어일 뿐이다.

this

ES6에서는 객체 내부에서 중괄호({})을 사용해서 추가적인 this 바인딩 없이 중괄호({})로 내용을 감싸는 것으로 동일한 this를 가리키도록 할 수 있다.

/* 기존 */
let value = 0;
let obj = {
  value: 5,
  setValue: function () {
    this.value = 10;
    (function () {
      this.value = 20;	// 여기서 this는 window를 가리킴
    }).call(this);	// 때문에 this 바인딩을 추가로 해줘야함
  }
};

let value = 0;
let obj = {
  value: 5,
  setValue: function () {
    this.value = 10;
     {
      this.value = 20;	// 외부의 this와 동일한 this를 가리킴
     }
  }
};

참조


좋은 웹페이지 즐겨찾기