본문으로 건너뛰기
Advertisement

1.5 엄격 모드 (Strict Mode)

엄격 모드란?

JavaScript의 **엄격 모드(Strict Mode)**는 ES5에서 도입된 기능으로, JavaScript의 느슨한(sloppy) 기본 동작 대신 더 엄격한 규칙을 적용하는 모드입니다.

"use strict"; // 이 한 줄이 엄격 모드를 활성화

// 이제 더 엄격한 규칙이 적용됩니다

엄격 모드 활성화 방법

전역 수준 (파일 전체)

"use strict";

// 파일 전체에 엄격 모드 적용
function example() {
// 이 함수도 엄격 모드
}

함수 수준

function strictFunction() {
"use strict"; // 이 함수에만 적용
// 엄격 모드
}

function normalFunction() {
// 비엄격 모드
}

ES 모듈 (자동 적용)

// .js 파일에서 import/export를 사용하면 자동으로 엄격 모드
import { something } from './module.js';

// "use strict" 없어도 엄격 모드!

클래스 (자동 적용)

class MyClass {
// 클래스 내부는 자동으로 엄격 모드
method() {
// 엄격 모드
}
}

비엄격 vs 엄격 모드 차이점

1. 미선언 변수 금지

// ❌ 비엄격 모드: 미선언 변수가 전역 변수로 생성됨 (버그의 원인!)
function nonStrict() {
x = 10; // 선언 없이 할당 → 전역 변수 x가 생성됨
console.log(x); // 10
}
nonStrict();
console.log(x); // 10 (전역 오염!)

// ✅ 엄격 모드: ReferenceError 발생
function strict() {
"use strict";
y = 20; // ReferenceError: y is not defined
}
strict();

2. this 바인딩 차이

// 비엄격 모드: 일반 함수의 this는 전역 객체 (브라우저: window, Node.js: global)
function showThis() {
console.log(this); // window (브라우저) or global (Node.js)
}
showThis();

// 엄격 모드: 일반 함수의 this는 undefined
function showThisStrict() {
"use strict";
console.log(this); // undefined
}
showThisStrict();
// 실용적인 예: 메서드를 변수에 담으면 this가 달라짐
class Button {
constructor(label) {
this.label = label;
}

handleClick() {
console.log(this.label); // undefined (this가 달라짐)
}
}

const btn = new Button('제출');
const handler = btn.handleClick;
handler(); // 비엄격: window.label (undefined), 엄격: TypeError

3. 중복 파라미터 금지

// ❌ 비엄격 모드: 중복 파라미터 허용 (마지막 값이 사용됨)
function duplicate(a, a, b) {
console.log(a, b); // 두 번째 a 값이 사용됨
}
duplicate(1, 2, 3); // 2 3

// ✅ 엄격 모드: SyntaxError
function strictDuplicate(a, a, b) { // SyntaxError: Duplicate parameter name
"use strict";
}

4. with 문 금지

const obj = { x: 10, y: 20 };

// ❌ 비엄격 모드: with 문 사용 가능 (성능과 가독성 문제)
with (obj) {
console.log(x + y); // 30 (obj.x + obj.y)
}

// ✅ 엄격 모드: SyntaxError
"use strict";
with (obj) { // SyntaxError: Strict mode code may not include a with statement
console.log(x + y);
}

5. delete 제한

// 비엄격 모드: delete 실패 시 false 반환
var x = 10;
console.log(delete x); // false (조용히 실패)

// 엄격 모드: TypeError 발생
"use strict";
var y = 20;
delete y; // SyntaxError: Delete of an unqualified identifier in strict mode
// 변수 삭제 vs 객체 프로퍼티 삭제
const obj = { a: 1, b: 2 };
delete obj.a; // OK: 객체 프로퍼티 삭제는 엄격 모드에서도 가능
console.log(obj); // { b: 2 }

// 설정 불가 프로퍼티 삭제
const obj2 = {};
Object.defineProperty(obj2, 'permanent', {
value: 42,
configurable: false,
});
delete obj2.permanent; // 비엄격: false, 엄격: TypeError

6. eval 스코프 격리

// 비엄격 모드: eval이 현재 스코프에 변수 추가 가능
eval("var leaked = 'I am leaked!'");
console.log(leaked); // 'I am leaked!' (스코프 오염)

// 엄격 모드: eval은 자신만의 스코프를 가짐
"use strict";
eval("var notLeaked = 'isolated'");
console.log(notLeaked); // ReferenceError: notLeaked is not defined

7. 읽기 전용 프로퍼티 쓰기 금지

// 비엄격 모드: 조용히 실패
const obj = {};
Object.defineProperty(obj, 'readOnly', {
value: 42,
writable: false,
});
obj.readOnly = 100; // 조용히 실패
console.log(obj.readOnly); // 42 (변경 안됨)

// 엄격 모드: TypeError 발생
"use strict";
obj.readOnly = 100; // TypeError: Cannot assign to read only property

엄격 모드를 사용해야 하는 이유

버그 예방

// 흔한 실수: 오타로 새 전역 변수 생성
"use strict";

let userName = "김철수";
userNmae = "이영희"; // ReferenceError! (오타: userNmae)
// 엄격 모드 없으면 조용히 전역 변수 생성 → 디버깅 어려움

보안 강화

"use strict";

function secureFunction() {
// 엄격 모드에서 this는 undefined (전역 객체 접근 불가)
if (this) {
// 이 코드는 실행되지 않음
globalThis.secretKey = '해킹';
}
}
secureFunction();

미래 JavaScript와의 호환성

엄격 모드는 미래 ECMAScript 버전에서 키워드가 될 예약어 사용을 금지합니다:

"use strict";

// 다음 식별자들은 엄격 모드에서 예약어
// implements, interface, let, package, private, protected, public, static, yield

let implements = 1; // SyntaxError (예약어)

실전 패턴: 엄격 모드 + 모던 JS

현대 JavaScript 개발에서는 다음 이유로 항상 엄격 모드가 적용됩니다:

// 1. ES 모듈 (import/export) → 자동 엄격 모드
import { helper } from './utils.js';

// 2. 클래스 → 자동 엄격 모드
class MyService {
process() { /* 엄격 모드 */ }
}

// 3. TypeScript → 항상 엄격 모드로 컴파일

// 4. Vite, webpack 같은 번들러 → 보통 엄격 모드 활성화

레거시 .js 파일(모듈이 아닌 스크립트)을 작성할 때는 파일 상단에 "use strict"를 명시하는 것이 좋습니다.


엄격 모드 전체 제약 요약

제약비엄격엄격
미선언 변수전역 변수 생성ReferenceError
함수의 this전역 객체undefined
중복 파라미터허용SyntaxError
with 문허용SyntaxError
변수 deletefalse (조용히 실패)SyntaxError
읽기 전용 프로퍼티 쓰기조용히 실패TypeError
eval 스코프현재 스코프 오염격리된 스코프
arguments.callee허용TypeError
8진수 리터럴 (0123)허용SyntaxError

고수 팁

엄격 모드 없는 코드 마이그레이션

기존 비엄격 모드 코드를 엄격 모드로 전환할 때 주의점:

// 1. 전역 변수 누수 수정
// 전: x = 10 → 후: let x = 10

// 2. with 문 제거
// 전:
with (obj) { console.log(name); }
// 후:
const { name } = obj;
console.log(name);

// 3. arguments.callee 대체
// 전:
function factorial(n) {
return n <= 1 ? 1 : n * arguments.callee(n - 1);
}
// 후:
function factorial(n) {
return n <= 1 ? 1 : n * factorial(n - 1);
}

ESLint로 엄격 모드 강제

// eslint.config.js
export default [
{
rules: {
'strict': ['error', 'global'], // 전역 엄격 모드 강제
},
},
];
Advertisement