SDK 모던 딥 다이브 스터디 7주차

민겸·2023년 6월 10일
0

SDK 스터디

목록 보기
6/6

7주차 주제는 엄격 모드(strict mode)이다.

책에서는 간단한 예제로 코드를 추론하게 하며 시작한다.

function foo() {
  x = 10;
}

console.log(x);

위 코드의 결과는 어떻게 될까?

foo함수 내에서 선언하지 않은 변수 x10을 할당했다. 이 때, 변수 x를 찾아야 값을 할당할 수 있기 때문에 자바스크립트 엔진은 변수 x가 어디에서 선언되었는지 스코프 체인을 통해 검색하기 시작한다.

먼저 foo함수의 스코프에서 변수 x를 검색하지만 선언된 변수가 없어서 실패한다. 자바스크립트 엔진은 변수 x를 검색하기 위해 foo 함수 컨텍스트의 상위 스코프인 전역 스코프에서 변수 x의 선언을 검색한다.

전역에서도 변수 x의 선언을 찾을 수 없기 때문에 ReferenceErrorthrow할 것 같지만 자바스크립트 엔진은 암묵적으로 전역 객체에 프로퍼티 x를 동적으로 생성한다. 이렇게 x는 전역 변수가 되고 이렇게 전역 변수가 된 변수를 암묵적 전역 변수(implicit global)이라고 한다.

개발자와의 의도와는 상관없는 이런 현상들은 오류를 발생시키는 원인이 될 가능성이 크다. 따라서 반드시 var, let, const 키워드를 사용하여 변수를 선언해야 한다.

하지만, 오타나 문법 지식의 미비로 인한 실수는 언제나 발생한다. 이런 실수를 근본적으로 해결하기 위해 ES5부터 strict mode가 추가되었다.

strict mode란

strict mode는 자바스크립트 언어의 문법을 보다 엄격히 적용하여 기존에는 무시되던 오류를 발생시킬 가능성이 높거나 자바스크립트 엔진의 최적화 작업에 문제를 일으킬 수 있는 코드에 대해 명시적인 에러를 발생시킨다.

ESLint와 같은 린트 도구를 사용하면 strict mode와 유사한 효과를 얻을 수 있다. 린트 도구는 정적 분석 기능을 통해 소스 코드를 실행하기 전에 스캔하여 문법적 오류나 잠재적 오류를 찾아내고 오류의 이유를 알려주는 유용한 도구이다.

strict mode 적용하기

strict mode를 적용하는 것은 어렵지 않다. 적용하고 싶은 스크립트 또는 함수의 최상단에 use strict; 를 추가하기만 하면 된다.

전역에 추가하면 스크립트 전체에 strict mode가 적용된다.

"use strict";

function foo() {
  x = 10; // ReferernceError: x is not defined
}

foo();

함수의 최상단에 추가하면 해당 함수와 중첩된 내부 함수에 strict mode가 적용된다.

function foo() {
  "use strict";
  
  x = 10; // ReferernceError: x is not defined
}

foo();

이렇게 적용하지 말자

전역 적용

전역에 적용한 strict mode스크립트 단위로 적용된다.

<!DOCTYPE html>
<html>
  <body>
    <script>
      "use strict";
    </script>
    <script>
      x = 1; // 에러가 발생하지 않는다.
      console.log(x);
    </script>
    <script>
      "use strict";
      y = 1; // ReferernceError: y is not defined
      console.log(y);
    </script>
  </body>
</html>

위와 같이 스크립트 단위로 적용되는 strict mode는 다른 스크립트에 영향을 주지 않는다. 게다가, 이렇게 strict mode 스크립트와 non-strict mode 스크립트가 섞이는 것은 바람직하지 않다. 외부 서드 파티 라이브러리를 사용하고 있고 해당 라이브러리가 non-strict mode일 경우 추적하기 힘든 오류를 발생시킬 수도 있다.

이러한 경우, 즉시 실행 함수로 스크립트 전체를 감싸서 스코프를 구분하고 즉시 실행 함수의 최상단에 strict mode를 적용해야 한다.

(function () {
  "use strict";
  // ...logic
}());

함수 단위 적용

위에 언급한 바와 같이 함수 단위로도 strict mode를 적용시킬 수 있다. 함수 또한 strict modenon-strict mode를 혼용하는 것은 바람직하지 않고 일일히 모든 함수에 strict mode를 적용하는 것은 귀찮은 일이다. 게다가 strict mode가 적용된 함수가 참조할 외부 함수의 컨텍스트에 strict mode를 적용하지 않는다면 이 또한 문제가 된다.

(function () {
  // non-strict mode
  var let = 10; // 에러가 발생하지 않는다.
  
  function foo() {
    'use strict';
    let = 20; // SyntaxError: Unexpected strict mode reserved word
  }
  foo();
}());

따라서 strict mode는 즉시 실행 함수로 감싼 스크립트 단위로 적용하는 것이 바람직하다.

strict mode가 하는 일

strict mode의 기능은 다음과 같다.

  • 선언하지 않은 변수를 참조하면 ReferenceError가 발생한다.
  • 객체의 프로퍼티가 아닌 변수, 함수, 매개변수를 delete로 삭제하려고 하면 SyntaxError가 발생한다.
  • 매개변수 이름이 중복되면 SyntaxError가 발생한다.
  • with문을 사용하면 SyntaxError가 발생한다.
  • 생성자 함수가 아닌 일반 함수에서는 thisundefined가 바인딩된다.
  • IE.9이하는 지원하지 않는다.

회고

ESLint를 쓰고 있어서 strict mode에 대한 필요성을 못 느껴왔다. ESLintstrict mode의 기능들을 포함한 슈퍼셋 느낌이기 떄문이다. 이참에 ESLint 설정을 커스텀해보는 것도 좋을 것 같다.

책에 대한 공부는 개인적으로 해도 되는 부분이지만 이때까지 어느정도의 강제성을 부여하기 위해 스터디를 해왔다. 하지만 스터디에서 결과물이 산출되면 좋을 것 같다는 의견이 모여 블로그 만들기를 시작하려 한다. 책의 진도는 주에 1장으로 줄이고 강제성은 블로그 쓰기로 결정되었고 블로그 만들기는 새로운 기술들에 대한 학습과 적용하며 체화하는 것이 주가 될 것 같다.

블로그 만들기 프로젝트 초기 설정을 할 때 ESLint에 대해서 좀 더 알아보고 직접 설정을 해봐야겠다.

profile
기술부채상환중...

0개의 댓글