코딩기록

JS)모던 자바스크립트 Deep Dive 20장 strict mode 본문

프론트/모던 자바스크립트 Deep Dive 책 스터디

JS)모던 자바스크립트 Deep Dive 20장 strict mode

뽀짝코딩 2024. 7. 25. 22:54
728x90

20장 strict mode

 

20-1. strict mode란?

  •    [예제 20-01]
       function foo() {
         x = 10;
       }
       foo();
       
       console.log(x); // ?
  • [예제 20-01] 코드 흐름
  • foo함수 내에서 선언하지 않은 x 변수에 값 10을 할당.
    1. 이때 x 변수를 찾아야 x에 값을 할당할 수 있기 때문에 자바스크립트 엔진은 x 변수가 어디에서 선언되었는지 스코프 체인을 통해 검색하기 시작함.
    2. 자바스크립트 엔진은 먼저 foo 함수의 스코프에서 x 변수의 선언을 검색함.
    3. foo 함수의 스코프에는 x 변수의 선언이 없으므로 검색에 실패할 것이고, 자바스크립트 엔진은 x 변수를 검색하기 위해 foo 함수 컨텍스트의 상위 스코프(여기선 전역 스코프)에서 x 변수의 선언을 검색함.
    4. 전역 스코프에도 x변수의 선언이 존재하지 않기 때문에 referenceError를 발생시킬 것 같지만 자바스크립트 엔진은 암묵적으로 전역 객체에 x 프로퍼티를 동적 생성. 
      • 이때 전역 객체의 x 프로퍼티는 마치 전역 변수처럼 사용할 수 있음. 이런 현상을 암묵적 전역(implicit global)이라 함.
      • 개발자의 의도와 상관없이 발생한 암묵적 전역은 오류를 발생시키는 원인 이 될 가능성이 크기 때문에 반드시 var, let, const 키워드를 사용해 변수를 선언한 다음 사용해야 함.
  • 암묵적 전역으로 인한 오류가 발생할 확률을 줄이고자 ES5부터 strict mode(엄격모드)가 추가됨.
  • strict mode(엄격모드)는 자바스크립트 언어의 문법을 좀 더 엄격히 적용하여 오류를 발생시킬 가능성이 높거나 자바스크립트 엔진의 최적화 작업에 문제를 일으킬 수 있는 코드에 대해 명시적 에러를 발생시킴.

 

  • ESLint
    ESLint 같은 도구를 사용해도 strict mode와 유사한 효과를 얻을 수 있음.
    린트 도구는 정적 분석 기능을 통해 소스코드를 실행하기 전에 소스코드를 스캔하여 문법적 오류만이 아니라 잠재적 오류까지 찾아내고 오류의 원인을 리포팅해 주는 유용한 도구.

 

 

20-2. strict mode의 적용

  • strict mode를 적용하려면 전역의 선두 또는 함수 몸체의 선두에 'use strict';를 추가.
  • 전역의 선두에 추가하면 스크립트 전체에 strict mode가 적용됨.
  •    [예제 20-02]
       'use strict';
       
       function foo() {
         x = 10; // ReferenceError: x is not defined
       }
       foo();

 

  • 함수 몸체의 선두에 추가하면 해당 함수와 중첩 함수에 strict mode가 적용됨.
  •    [예제 20-03]
       function foo() {
         'use strict';
       
         x = 10; // ReferenceError: x is not defined
       }
       foo();

 

  • 코드의 선두에 'use strict';를 위치시키지 않으면 strict mode가 제대로 동작하지 않음.
  •    [예제 20-04]
       function foo() {
         x = 10; // 에러를 발생시키지 않는다.
         'use strict';
       }
       foo();

 

 

20-3. 전역에 strict mode를 적용하는 것은 피하자

  • 전역에 적용한 strict mode는 스크립트 단위로 적용됨.
  • 스크립트 단위로 적용된 strict mode는 다른 스크립트에 영향을 주지 않고 해당 스크립트에 한정되어 적용됨.
  •     [예제 20-05]
         <! DOCTYPE html >
           <html>
             <body>
               <script>
                 'use strict';
               </script>
               <script>
                 x = 1; // 에러가 발생하지 않음.
                 console.log(x); // 1
               </script>
               <script>
                 'use strict';
       
                 y = 1; // ReferenceError: y is not defined
                 console.log(y);
               </script>
             </body>
           </html>

 

  • strict mode와 non-strict mode 스크립트를 혼용하는 것은 오류를 발생시킬 수 있음.
    • 이러한 경우 즉시 실행 함수로 스크립트 전체를 감싸서 스코프를 구분하고 즉시 실행 함수의 선두에 strict mode를 적용.
    •     [예제 20-06]
           // 즉시 실행 함수의 선두에 strict mode 적용
           (function () {
             'use strict';
         
             // Do something...
           }());

 

 

20-4. 함수 단위로 strict mode를 적용하는 것도 피하자 

  • 함수 단위로 strict mode를 적용할 수 있으나
    • 어떤 함수는 strict mode를 적용하고 어떤 함수는 strict mode를 적용하지 않는 것은 바람직하지 않으며
      모든 함수에 일일이 strict mode를 적용하는 것은 번거로움.
    • 그리고 strict mode가 적용된 함수가 참조할 함수 외부의 컨텍스트에 strict mode를 적용하지 않는다면 이 또한 문제가 발생할 수 있음.
    •     [예제 20-07]
           (function () {
             // non-strict mode
             var lеt = 10; // 에러가 발생하지 않는다.
         
             function foo() {
               'use strict';
         
               let = 20; // SyntaxError: Unexpected strict mode reserved word
             }
             foo();
           }());
  • 따라서 strict mode는 즉시 실행 함수로 감싼 스크립트 단위로 적용하는 것이 바람직함.

 

 

20-5. strict mode가 발생시키는 에러 

 

1). 암묵적 전역

  • 선언하지 않은 변수를 참조하면 ReferenceError가 발생.
  •     [예제 20-08]
         (function () {
           'use strict';
       
           x = 1;
           console.log(x); // ReferenceError: x is not defined
         }());
 

 

2). 변수, 함수, 매개변수의 삭제

  • delete 연산자로 변수, 함수, 매개변수를 삭제하면 SyntaxError가 발생.
  •     [예제 20-09]
         (function () {
           'use strict';
       
           var x = 1;
           delete x;
           // SyntaxError: Delete of an unqualified identifier in strict mode.
       
           function foo(a) {
             delete a;
             // SyntaxError: Delete of an unqualified identifier in strict mode.
           }
           delete foo;
           // SyntaxError: Delete of an unqualified identifier in strict mode.
         }());

 

3). 매개변수 이름의 중복

  • 중복된 매개변수 이름을 사용하면 SyntaxError가 발생.
  •     [예제 20-10]
         (function () {
           'use strict';
       
           //SyntaxError: Duplicate parameter name not allowed in this context
           function foo(x, x) {
             return x + x;
           }
           console.log(foo(1, 2));
         }());

 

4). with 문의 사용

  • with문을 사용하면 SyntaxError가 발생.
  • with문은 동일한 객체의 프로퍼티를 반복해서 사용할 때 객체 이름을 생략할 수 있어서 코드가 간단해지는 효과가 있지만 성능과 가독성이 나빠지는 문제가 있기 때문에 with문은 사용하지 않는 것이 좋음.
  •     [예제 20-11]
        (function () {
           'use strict';
       
           // SyntaxError: Strict mode code may not include a with statement
           with ({ x: 1 }) {
             console.log(x);
           }
         }());

 

20-6. strict mode 적용에 의한 변화 

1). 일반 함수의 this

  • strict mode에서 함수를 일반 함수로서 호출하면 this에 undefined가 바인딩됨.
    • 생성자 함수가 아닌 일반 함수 내부에서는 this를 사용할 필요가 없기 때문.
    • 이때 에러는 발생하지 않음.
    •     [예제 20-12]
           (function () {
             'use strict';
         
             function foo() {
               console.log(this); // undefined
             }
             foo();
         
             function Foo() {
               console.log(this); // Foo
             }
             new Foo();
           }());

 

2). arguments 객체

  • strict mode에서는 매개변수에 전달된 인수를 재할당하여 변경해도 arguments 객체에 반영되지 않음.
  •     [예제 20-13]
         (function (a) {
           'use strict';
           // 매개변수에 전달된 인수를 재할당하여 변경
           a = 2;
       
           // 변경된 인수가 arguments 객체에 반영되지 않음.
           console.log(arguments); // { 0: 1, length: 1 }
         }(1));
       

 

덧) 스터디에서 나온 이런저런 내용 240726금-

strict mode - 명시적으로 기입할 필요가 없다, 그냥 모듈을 써라.

319p [예제 20-13]
매개변수에서 전달된 인수를 함수 내부에서 고치는게 나쁘다.
매개변수 재할당 하지 마라.
es6에서는 arguments 말고 다른거 씀.

 

 

 

 

 

 

 

참고

도서 - 모던 자바스크립트 Deep Dive -이웅모

이웅모 강사님 홈피  -  https://poiemaweb.com/js-prototype

이웅모 강사님 유튜브  -  https://www.youtube.com/watch?v=0AjTZG6bGq8

 

 

✅ 덧, 부분은 스터디 내용을 기억에 의존해서 쓴 글이라 틀린 부분이 있다면 댓글 부탁드립니다.- 뽀짝코딩 주인장-

 

 

 

반응형
Comments