strict mode(엄격 모드)란, 자바스크립트 언어 문법을 엄격히 적용하여 오류를 발생시킬 가능성이 높은 코드에 대해 에러를 발생시키는 것을 말한다.
예를 들어,
function foo() {
x = 1;
}
foo();
console.log(x);
위 예제에서 선언하지 않은 x 변수에 1이라는 값을 할당했다. 자바스크립트 엔진은 x 변수를 검색하기 위해 foo 함수의 상위 스코프에서 x 변수의 선언을 검색한다. 그러나 자바스크립트 엔진은 암묵적으로 전역 객체에 x 프로퍼티를 동적 생성하고 전역 변수처럼 사용할 수 있게 한다. 이를 암묵적 전역(implicit global
)이라 한다.
암묵적 전역은 개발자 의도와는 상관없이 발생하여 오류를 발생시키는 원인이 될 수 있다. 그래서 오류를 발생시키기 어려운 환경에서 안정적인 코드를 생산하기 위해 strict mode라는 것이 추가된 것이다.
stict mode를 적용하려면 전역의 선두나 함수 몸체의 선두에 'use strict';
를 추가하면 된다.
ex) 전역에 적용
'use strict';
function foo() {
x = 1; // ReferenceError
}
foo();
그러나 전역에 적용하는 것은 피하는 것이 좋다. 전역에서는 strict mode가 스크립트 단위로 적용되는데, 해당 스크립트가 아닌 다른 스크립트에는 영향을 주지 않는다.
외부 라이브러리를 사용하는 경우 라이브러리가 non-strict mode인 경우가 있기 때문에 strict mode와 non-strict mode를 혼용해서 사용하는 것은 바람직하지 않다.
ex) 함수에 적용
function foo() {
'use strict';
x = 1; // ReferenceError
}
foo();
함수 역시 stict mode와 non-strict mode를 혼용하는 것은 좋지 않고 모든 함수에 일일이 적용하는 것은 번거롭다.
따라서 strict mode는 즉시 실행 함수로 감싸 스크립트 단위로 적용하는 것이 좋다.
(function (){
var y = 0;
function foo() {
'use strict';
y = 10; // SyntaxError
}
foo();
}());
📌 strict mode는 코드의 선두에 위치하지 않으면 제대로 동작하지 않는다. 적용할 때는 즉시 실행 함수로 감싸는 것이 좋다.
선언하지 않은 변수를 참조했을 때 ReferenceError
가 발생한다.
// implicit global
(function () {
'use strict';
x = 1;
console.log(x); // ReferenceError
}());
변수, 매개변수, 함수를 delete
로 삭제하면 SyntaxError
가 발생한다.
// variable, parameter, function delete
(function() {
'use strict';
var a = 0;
delete a; // SyntaxError
function foo(b) {
delete b; // SyntaxError
}
delete foo; // SyntaxError
}());
중복된 매개변수 이름을 사용하면 SyntaxError
가 발생한다.
// Duplicate parameter name
(function() {
'use strict';
// SyntaxError
function foo(x, x){
return x + x;
}
console.log(foo(2, 4));
}());
with
문을 사용하면 SyntaxError
가 발생한다.
// with statement
(function() {
'use strict';
// SyntaxError
with({x: 5}){
console.log(x);
}
console.log(foo(2, 4));
}());
strict mode에서 일반 함수를 호출하면 this에 undefined가 바인딩된다. 생성자 함수가 아닌 일반 함수에서는 this를 사용할 필요가 없기 때문이다. 에러는 발생하지 않는다.
// this
(function() {
'use strict';
function foo(){
console.log(this); // undefined
}
foo();
}());
strict mode에서 매개변수에 전달된 인수를 재할당해도 arguments 객체에는 변경된 값이 반영되지 않는다.
// arguments
(function(x) {
'use strict';
x = 3;
console.log(arguments); // [Arguments] { '0': 2 }
}(2));