본문으로 건너뛰기
김신건의 로그

[Javascript] strict mode

· 수정 · 📖 약 2분 · 815자/단어 #javascript #strict-mode #fundamentals #es5
JS strict mode, use strict, 엄격 모드

정의

'use strict' 디렉티브로 활성화되는 엄격 실행 모드. ES5 도입. 위험한 문법을 에러로 만들어 코드 안전성 향상.

ES module 과 class 본문은 자동으로 strict mode.

사용 상황

상황strict 관련
ES module (Vite, webpack, bundler)자동 strict
class 내부자동 strict
Node.js .mjs 파일자동 strict
레거시 <script> 태그명시적 'use strict' 필요
라이브러리 배포 코드반드시 strict

현대 개발 환경에서는 번들러가 ES module 을 사용하므로 별도 선언 없이도 strict mode 가 적용된다.

strict mode 활성화 흐름

flowchart TD
    A[JavaScript 파일 파싱] --> B{파일 타입?}
    B -->|"ES module (.mjs, type=module)"| C[자동 strict mode]
    B -->|일반 script 파일| D{"'use strict' 선언?"}
    D -->|파일 최상단| C
    D -->|함수 내부| E["해당 함수만 strict mode"]
    D -->|없음| F["sloppy mode (기본값)"]
    A --> G{"class 본문?"}
    G -->|해당 블록| C

사용

// 파일 최상단
'use strict';

// 또는 함수 내부
function foo() {
    'use strict';
    // ...
}

strict mode 의 효과

1. 선언 안 한 변수에 할당 시 ReferenceError

// sloppy
function foo() {
    x = 1;     // 실수로 var 빼먹음 → global 변수 생성!
}

// strict
function foo() {
    'use strict';
    x = 1;     // ❌ ReferenceError
}

global 오염 방지.

2. 중복 매개변수 금지

function foo(a, a) { }      // sloppy 에서는 동작
// 'use strict'; → SyntaxError

3. 8 진수 리터럴 금지

const x = 010;          // sloppy: 8 (8진수 8)
'use strict';
const x = 010;          // ❌ SyntaxError
const y = 0o10;         // ES6 표준 8진수 표기

4. delete 의 제한

'use strict';
delete Object.prototype;     // ❌ TypeError (변경 불가)

var x = 1;
delete x;                     // ❌ SyntaxError (변수 삭제 불가)

5. this 의 변화

function foo() {
    console.log(this);
}

foo();                  // sloppy: window/global
'use strict';
foo();                  // strict: undefined

명시적으로 this 를 지정하지 않은 호출에서 더 안전.

6. with 금지

'use strict';
with (obj) { }     // ❌ SyntaxError

7. arguments 의 immutable

function foo(a) {
    'use strict';
    a = 99;
    console.log(arguments[0]);    // 호출 시 전달된 원본 값
}

sloppy 모드에서는 a 변경이 arguments[0] 에 반영. strict 는 분리.

8. eval 의 격리

'use strict';
eval('var x = 1;');
console.log(x);     // ❌ ReferenceError (eval 내부 스코프)

sloppy 모드에서는 eval 안의 변수가 호출 스코프에 누설.

9. 미래 예약어 보호

implements, interface, let, package, private, protected, public, static, yield 가 식별자 금지.

전체 제한 목록

제한sloppystrict
선언 없는 변수 할당전역 생성ReferenceError
중복 파라미터허용SyntaxError
8진수 리터럴 0NNN허용SyntaxError
with허용SyntaxError
delete 변수/함수무시SyntaxError
delete non-configurable무시TypeError
this (일반 함수 호출)window/globalundefined
arguments 와 파라미터 동기화동기화 됨분리
eval 변수 누설누설 됨격리
미래 예약어 사용허용SyntaxError

언제 자동으로 strict 인가

flowchart LR
    A[코드 실행] --> B{strict mode?}
    B -->|아님| C[위험한 코드 허용]
    B -->|strict| D[위험한 코드 차단]
    C --> E[선언 없는 변수, 전역 생성]
    C --> F[with 문 허용]
    D --> G[ReferenceError 발생]
    D --> H[SyntaxError 발생]
  • ES module (.mjs, <script type="module">, modern build tools)
  • class 본문
  • export / import 사용 파일

따라서 현대 코드는 보통 자연스럽게 strict.

TypeScript 와의 관계

TypeScript 는 항상 strict mode 로 컴파일된다. TS 에서 'use strict' 를 명시적으로 쓸 필요 없다.

tsconfig.json"strict": true 는 TypeScript 타입 엄격 모드로, JS 'use strict' 와는 별개 개념이지만 함께 동작한다.

레거시 코드 마이그레이션 전략

// 1단계: 파일 단위로 strict 추가 후 에러 수집
'use strict';
// ... 기존 코드 ...

// 2단계: ReferenceError, TypeError, SyntaxError 목록 확인
// - 미선언 변수 → var/let/const 추가
// - delete 오용 → 로직 수정
// - with 문 → 객체 구조 분해로 교체

// 3단계: 테스트 통과 확인 후 진행

IMPORTANT

레거시 스크립트 파일 전체에 한 번에 'use strict' 를 추가하면 예상치 못한 에러가 발생할 수 있다. 파일 단위로 점진적으로 적용하고, 테스트를 충분히 작성한 후 진행.

모범 사례

  1. 항상 'use strict' (또는 ES module 사용)
  2. 함수 단위 strict 는 옛 스타일, 파일 단위 권장
  3. 라이브러리 코드는 반드시 strict
  4. ESLint 'strict': 'error' 규칙으로 강제

호환성

모든 브라우저 + Node.js 가 지원. legacy IE5 같은 환경 외에는 문제 없음.

sloppy mode 의 함정 (왜 strict 가 필요한가)

// 1. global 오염
foo = 1;
function setup() {
    foo = 99;     // 의도와 다르게 global foo 변경
}

// 2. NaN 비교
NaN === NaN;     // false (이건 strict 무관)

// 3. with 의 스코프 폭주
with (obj) {
    a = 1;        // obj.a 인지 외부 a 인지 모호
}

strict 가 이런 함정의 상당수를 컴파일 / 런타임 에러로 잡아준다.

Node.js 에서의 strict mode

Node.js 의 .mjs 파일과 type: "module" 을 설정한 .js 파일은 자동 strict. CommonJS (.cjs 또는 기본 .js) 는 명시적으로 선언 필요.

// CommonJS: 명시 필요
'use strict';
const x = 1;

// ES module (.mjs 또는 package.json type: module): 자동 strict
export const x = 1;

Node.js 18+ 에서는 최상위 await 를 위해서도 ES module 이 필요하고, 이때 strict 도 함께 자동 적용된다.

관련 위키

이 글의 용어 (5개)
[Javascript] 스코프 체인javascript
정의 스코프 체인 (Scope Chain) 은 변수 식별자를 해결할 때 따라가는 중첩된 의 연결 구조. 안쪽 스코프에서 찾지 못한 변수를 바깥 스코프로 차례로 검색. 시각화 변수…
[Javascript] 호이스팅 (Hoisting)javascript
정의 호이스팅 (Hoisting) 은 JavaScript 엔진이 코드를 실행하기 전 바인딩 생성 단계 에서 스코프 내의 선언을 파악하고 등록하는 메커니즘이다. 마치 선언이 스코프…
[Javascript] ES Modules (import / export)javascript
정의 ES Modules (ESM) 은 표준 JS 모듈 시스템 (ES6). / 키워드. 브라우저와 Node.js 16+ 모두 지원. export named export defau…
[Javascript] this 바인딩javascript
정의 JavaScript 의 는 호출 방식에 따라 결정 되는 동적 바인딩. 4 가지 호출 방식 + arrow function (lexical) 규칙. 5 가지 규칙 | # | 규…
[Javascript] var / let / constjavascript
정의 JavaScript 의 3 가지 변수 선언 키워드. | 키워드 | 스코프 | 재할당 | 재선언 | 호이스팅 | |:---|:---|:---:|:---:|:---| | | f…

이 개념을 다룬 위키 페이지 (1)

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기