JavaScript ES6+ (1) Block scope

염겨레·2020년 11월 2일
1

javascript-ES6-basic

목록 보기
1/8

이 글은 정재남 개발자님의 인프런 강의인 JavaScript ES6+ 제대로 알아보기 초급편을 정리한 내용입니다.

1. 블록 스코프(block scope)

  • 함수 스코프: 함수에 의해서 생기는 변수의 유효 범위. 기존 var 해당.
  • 블록 스코프: 블록 {}에 의해서 생기는 변수의 유효 범위. let, const 해당.

아래 코드를 보면 var 변수는 함수 스코프를 가지므로 함수 내부에 선언한 num 변수를 함수 바깥에서 접근할 수 없음을 알 수 있다.

(function() {
  var num = 100;
  (function() {
    var num = 200;
	console.log(num);	// 200
  })();
  console.log(num);		// 100
})();
console.log(num);		// num is not defined

블록 스코프를 갖는 let으로 대체해 위 코드와 동일하게 작성한 코드는 아래와 같다.

{
  let num = 100;
  {
    let num = 200;
    console.log(num);	// 200
  }
  console.log(num);	// 100
}
console.log(num);	// num is not defined

2. TDZ(Temporal Dead Zone)

TDZ는 ECMAscript 정식 명칭은 아니지만 번역하면 임시사각지대라고 한다. DMZ 같은 느낌인가? 아래 코드를 먼저 보자.

if(true) {
  let num = 100;
  if(true) {
    console.log(num);	// 주목!!!!!
    const num = 200;
  }
  console.log(num);
}
console.log(num);        

주목이라고 주석 처리된 곳의 num의 출력은 어떻게 나올까?

가정 1) 호이스팅이 된다면? 바로 아래 const로 선언된 num 변수가 호이스팅되고 reference 에러가 발생한다.
가정 2: 호이스팅이 되지 않는다면? 바깥에서 num에 해당하는 변수를 찾아 출력해 100을 출력한다.

정답은 호이스팅이 적용돼 reference 에러가 발생하는 것이다. 변수 let이나 const에 대해서 변수가 선언된 위치에 오기 전에 변수를 호출할 수 없는 지역을 TDZ라고 한다. 기존 var는 호이스팅으로 변수를 끌어올리고 undefined를 할당하는 반면, let, const는 호이스팅으로 변수를 끌어올리고 할당하는 과정은 빠져 reference 에러가 발생하는 것이다.

3. this의 이해

예시를 먼저 보자.

let value = 0;
let obj = {
  value: 10,
  setValue: function() {
    this.value = 20;		// this: obj
    (function() {
      this.value = 50;		// this: window or global
    })();
  }
};

obj.setValue();

console.log(value);		// 50
console.log(obj.value);		// 20

obj 내부에 setValue라는 이름의 함수를 정의하고, obj.setValue()로 메소드로 호출했다. 이때 함수 내부에 첫번째 thisobj를 가리킨다. 그 이유는 메소드로 호출했을 때의 바로 앞의 객체를 가리키기 때문이다. 하지만 두번째 this는 window를 가리킨다. 함수로 바로 실행했을 때는 전역 객체를 가리키기 때문이다.

첫번째 this와 두번째 this를 같게 하기 위해서는 다음과 같은 방법들이 있다.
1) this를 변수에 할당하기

setValue: function() {
  this.value = 20;
  let self = this;
  (function() {
    self.value = 50;
  })();
}

2) call이나 bind로 변수 할당하기

setValue: function() {
  this.value = 20;
  (function() {
    this.value = 50;
  }).call(this);
}

3) 블록 스코프로 감싸기
this는 블록 스코프에 영향을 받지 않으므로!

setValue: function() {
  this.value = 20;
  {
    this.value = 50;
  }
}
profile
차근차근 나아가는 시나브로 개발자

0개의 댓글