Changes in Strict Mode
Strict Mode를 적용하면 코드에서는 다음과 같은 변화가 생깁니다.
Converting mistakes into Errors
- 선언하지 않은 변수에 값을 할당할 수 없습니다.
js
"use strict";
let mistypeVariable;
// Assuming no global variable mistypeVarible exists
// this line throws a ReferenceError due to the
// misspelling of "mistypeVariable" (lack of an "a")
mistypeVarible = 17;
- non-writable 전역변수나 속성(property), getter-only property, non-extensible object에 속성을 추가하면 에러가 발생합니다.
js
"use strict";
// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError
js
"use strict";
// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // throws a TypeError
js
"use strict";
// Assignment to a getter-only property
var obj2 = {
get x() {
return 17;
},
};
obj2.x = 5; // throws a TypeError
js
"use strict";
// Assignment to a new property on a non-extensible object
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // throws a TypeError
- 삭제할 수 없는 속성을 삭제하면 에러가 발생합니다.
js
"use strict";
delete Object.prototype; // throws a TypeError
- 함수인자의 이름이 겹치면 에러가 발생합니다.
js
function sum(a, a, c) {
// !!! syntax error
"use strict";
return a + a + c; // wrong if this code ran
}
- 팔진수(octal number)를 표시할 때 0-prefix를 붙이면 에러가 발생합니다.
js
"use strict";
var sum =
015 + // !!! syntax error
197 +
142;
var sumWithOctal = 0o10 + 8; // 대신 ES2015의 0o-prefix를 사용하면 됩니다
console.log(sumWithOctal); // 16
- primitive value에 속성을 추가하면 에러가 발생합니다.
js
(function () {
"use strict";
false.true = ""; // TypeError
(14).sailing = "home"; // TypeError
"with".you = "far away"; // TypeError
})();
- 객체에 중복된 속성이 있는 경우 에러가 발생합니다(ES5 기준)
js
"use strict";
var o = { p: 1, p: 2 }; // syntax error prior to ECMAScript 2015
TIP
ES2015에서는 computed property names로 뒤에 있는 중복된 속성이 앞의 속성을 덮어쓰기 때문에 문제가 되지 않습니다.
Simplifying variable uses
- with 구문을 사용하면 에러가 발생합니다.
js
"use strict";
var x = 17;
with (obj) {
// !!! syntax error
// If this weren't strict mode, would this be var x, or
// would it instead be obj.x? It's impossible in general
// to say without running the code, so the name can't be
// optimized.
x;
}
eval("")
syntax의 내부 expression에서 발생하는 일은eval
를 포함하는 주변 scope에 영향을 주지 않습니다.
js
"use strict";
var x = 2,
y = 3;
// NB: Strictness propagates into eval code evaluated by a
// direct call to eval — a call occurring through an
// expression of the form eval(...).
print(eval("var x = 5; x")); // prints 5
print(eval("var x = 7; x")); // prints 7
print(eval("y")); // prints 3
print(x); // prints 2
- 객체의 속성을 제외한 일반변수에
delete
연산을 적용하면 에러가 발생합니다.
js
"use strict";
var x;
delete x; // !!! syntax error
eval("var y; delete y;"); // !!! syntax error
Making eval and arguments simpler
eval
,arguments
의 바인딩(binding)이나 할당(assigning)을 차단합니다.
js
"use strict";
// assigning disabled!
eval = 17;
arguments++;
++eval;
// binding disabled!
var obj = { set p(arguments) {} };
var eval;
try {
} catch (arguments) {}
function x(eval) {}
function arguments() {}
var y = function eval() {};
var f = new Function("arguments", "'use strict'; return 17;");
arguments
는 함수가 실행될 때 전달된 인자들의 정보만 가집니다.
js
function f(a) {
"use strict";
a = 42;
return [a, arguments[0]]; // strict mode가 아니었다면 arguments[0]에 a값이 저장됩니다.
}
var pair = f(17);
console.assert(pair[0] === 42);
console.assert(pair[1] === 17);
Securing Javascript
- 함수 내부에서
this
를 지정하지 않으면 globalThis 대신undefined
를 가집니다.
js
"use strict";
function fun() {
return this;
}
console.assert(fun() === undefined);
console.assert(fun.call(2) === 2);
console.assert(fun.apply(null) === null);
console.assert(fun.call(undefined) === undefined);
console.assert(fun.bind(true)() === true);
- 함수 내부에서 함수의
caller
,arguments
를 사용할 수 없습니다.
js
function fun(a, b) {
"use strict";
var v = 12;
return arguments.caller; // throws a TypeError
}
fun(1, 2); // doesn't expose v (or a or b)
Paving the way for future ECMAScript versions
미래에 새로운 ECMAScript의 새로운 syntax나 기능들을 공개될 수 있도록 스포일러를 방지합니다.
- 아래 리스트에 포함된 이름들은 reserved keyword로 변수명, 함수명, 인자명으로 사용할 수 없습니다.
- implements
- interface
- let
- package
- private
- protected
- public
- static
- yield
- script나 function의 상단에 함수를 정의하지 않으면 에러가 발생합니다(근데 ES2015에서는 허용된다).
js
"use strict";
if (true) {
function f() {} // !!! syntax error
f();
}
for (var i = 0; i < 5; i++) {
function f2() {} // !!! syntax error
f2();
}
function baz() {
// kosher
function eit() {} // also kosher
}