[πŸ“– λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ λ”₯λ‹€μ΄λΈŒ] 20μž₯. strict mode

λ…Έμ˜μ™„Β·2023λ…„ 11μ›” 14일
0

JavaScript(Deep Dive)

λͺ©λ‘ 보기
16/23
post-thumbnail

strict mode

1. strict modeλž€?

// μ‹€ν–‰κ²°κ³Όλ₯Ό μ˜ˆμΈ‘ν•΄λ³΄μ„Έμš”.
function foo() {
  x = 10;
}
foo();

console.log(x); // ?

foo ν•¨μˆ˜λ‚΄μ— μ„ μ–Έν•˜μ§€ μ•Šμ€ x λ³€μˆ˜μ— κ°’ 10을 ν• λ‹Ή 이 λ•Œ x λ³€μˆ˜λ₯Ό μ°Ύμ•„μ•Ό x에 값을 ν• λ‹Ήν•  수 있기 λŒ€λ¬Έμ— μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 x λ³€μˆ˜κ°€ μ–΄λ””μ—μ„œ μ„ μ–Έλ˜μ—ˆλŠ”μ§€ μŠ€μ½”ν”„μ²΄μΈμ„ 톡해 κ²€μƒ‰ν•˜κΈ° μ‹œμž‘. ν•˜μ§€λ§Œ foo ν•¨μˆ˜ μŠ€μ½”ν”„μ—μ„œλ„ κ·Έ μƒμœ„ μŠ€μ½”ν”„μ—μ„œλ„ x λ³€μˆ˜μ˜ 선언이 μ—†μœΌλ―€λ‘œ 검색에 μ‹€νŒ¨

그럼 λ‹Ήμ—°νžˆ ReferenceErrorλ₯Ό λ°œμƒμ‹œν‚¬ 것 κ°™μ§€λ§Œ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 μ•”λ¬΅μ μœΌλ‘œ μ „μ—­ 객체에 xν”„λ‘œνΌν‹°λ₯Ό 동적 생성. 이 λ•Œ μ „μ—­ 객체의 x ν”„λ‘œνΌν‹°λŠ” 마치 μ „μ—­ λ³€μˆ˜μ²˜λŸΌ μ‚¬μš©ν• μˆ˜ 있고 μ΄λŸ¬ν•œ ν˜„μƒμ„ 암묡적 전역이라 ν•œλ‹€.

μ΄λŸ¬ν•œ 암묡적 μ „μ—­ ν˜„μƒμ€ 였λ₯˜λ₯Ό λ°œμƒμ‹œν‚€λŠ” 원인이 될 κ°€λŠ₯성이 맀우 크닀. 이λ₯Ό 막기 μœ„ν•΄ ES5λΆ€ν„° strict mode(엄격 λͺ¨λ“œ)κ°€ μΆ”κ°€λ˜μ—ˆλ‹€. strict modeλŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ μ–Έμ–΄μ˜ 문법을 μ’€ 더 μ—„κ²©νžˆ μ μš©ν•˜μ—¬ 였λ₯˜λ₯Ό λ°œμƒμ‹œν‚¬ κ°€λŠ₯성이 λ†’κ±°λ‚˜ μžλ°”μŠ€ν¬λ¦½νŠΈ μ—”μ§„μ˜ μ΅œμ ν™” μž‘μ—…μ— 문제λ₯Ό μΌμœΌν‚¬ 수 μžˆλŠ” μ½”λ“œμ— λŒ€ν•΄ λͺ…μ‹œμ μΈ μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚¨λ‹€.

2. strict mode의 적용

strict modeλ₯Ό μ μš©ν•˜λ €λ©΄ μ „μ—­μ˜ 선두 λ˜λŠ” ν•¨μˆ˜ λͺΈμ²΄μ˜ 선두에 'use strict;'λ₯Ό μΆ”κ°€ν•œλ‹€.

βœ” μ „μ—­μ˜ 선두에 μΆ”κ°€ν•˜λ©΄ 슀크립트 전체에 strict modeκ°€ μ μš©λœλ‹€.

βœ” ν•¨μˆ˜ λͺΈμ²΄μ˜ 선두에 μΆ”κ°€ν•˜λ©΄ ν•΄λ‹Ή ν•¨μˆ˜μ™€ 쀑첩 ν•¨μˆ˜μ— strict modeκ°€ μ μš©λœλ‹€.

βœ” μ½”λ“œμ˜ 선두에 'use strict;'λ₯Ό μœ„μΉ˜μ‹œν‚€μ§€ μ•ŠμœΌλ©΄ strict modeκ°€ μ œλŒ€λ‘œ λ™μž‘ν•˜μ§€ μ•ŠλŠ”λ‹€.

function foo() {
  x = 10;
  'use strict';
}
foo();

3. 전역에 strict modeλ₯Ό μ μš©ν•˜λŠ” 것은 ν”Όν•˜μž

전역에 μ μš©ν•œ strict modeλŠ” 슀크립트 λ‹¨μœ„λ‘œ μ μš©λœλ‹€.

<!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λŠ” λ‹€λ₯Έ μŠ€ν¬λ¦½νŠΈμ— 영ν–₯을 주지 μ•Šκ³  ν•΄λ‹Ή μŠ€ν¬λ¦½νŠΈμ— ν•œμ •λ˜μ–΄ 적용.

strict mode 와 non-strict modeλ₯Ό ν˜Όμš©ν•΄μ„œ μ‚¬μš©ν•˜λ©΄ 였λ₯˜λ₯Ό λ°œμƒμ‹œν‚¬ 수 μžˆλ‹€. 특히 μ™ΈλΆ€ μ„œλ“œνŒŒν‹° 라이브러리λ₯Ό μ‚¬μš©ν•˜λŠ” 경우 λΌμ΄λΈŒλŸ¬λ¦¬κ°€ non-strict mode인 κ²½μš°λ„ 있기 λ•Œλ¬Έμ— 전역에 strict modeλ₯Ό μ μš©ν•˜λŠ” 것은 λ°”λžŒμ§ν•˜μ§€ μ•Šλ‹€.

μ΄λŸ¬ν•œ 경우 μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜λ‘œ 슀크립트 전체λ₯Ό κ°μ‹Έμ„œ μŠ€μ½”ν”„λ₯Ό κ΅¬λΆ„ν•˜κ³  μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜μ˜ 선두에 strict modeλ₯Ό 적용.

4. ν•¨μˆ˜ λ‹¨μœ„λ‘œ strict modeλ₯Ό μ μš©ν•˜λŠ” 것도 ν”Όν•˜μž

ν•¨μˆ˜λ‹¨μœ„λ‘œ 일일이 strict modeλ₯Ό μ μš©ν•˜λŠ” 것은 번거둜운 일이닀.

그리고 strict modeκ°€ 적용된 ν•¨μˆ˜κ°€ μ°Έμ‘°ν•  ν•¨μˆ˜ μ™ΈλΆ€μ˜ μ»¨ν…μŠ€νŠΈμ— strict modeλ₯Ό μ μš©ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆλ‹€.

(function () {
  // non-strict mode
  var lΠ΅t = 10; // μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.

  function foo() {
    'use strict';

    let = 20; // SyntaxError: Unexpected strict mode reserved word
  }
  foo();
}());

λ”°λΌμ„œ strict modeλŠ” μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜λ‘œ 감싼 슀크립트 λ‹¨μœ„λ‘œ μ μš©ν•˜λŠ” 것이 λ°”λžŒμ§.

5. strict modeκ°€ λ°œμƒμ‹œν‚€λŠ” μ—λŸ¬

strict modeλ₯Ό μ μš©ν–ˆμ„ λ•Œ μ—λŸ¬κ°€ λ°œμƒν•˜λŠ” λŒ€ν‘œμ μΈ 사둀

βœ” 암묡적 μ „μ—­

μ„ μ–Έν•˜μ§€ μ•Šμ€ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λ©΄ ReferenceErrorκ°€ λ°œμƒ

(function () {
  'use strict';
  
  x = 1;
  console.log(x); // ReferenceError: x is not defined
}());

βœ” λ³€μˆ˜, ν•¨μˆ˜, λ§€κ°œλ³€μˆ˜μ˜ μ‚­μ œ

deleteμ—°μ‚°μžλ‘œ λ³€μˆ˜, ν•¨μˆ˜, λ§€κ°œλ³€μˆ˜λ₯Ό μ‚­μ œν•˜λ©΄ SyntaxErrorκ°€ λ°œμƒν•œλ‹€.

(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.
}());

βœ” λ§€κ°œλ³€μˆ˜ μ΄λ¦„μ˜ 쀑볡

μ€‘λ³΅λœ λ§€κ°œλ³€μˆ˜ 이름을 μ‚¬μš©ν•˜λ©΄ SyntaxErrorκ°€ λ°œμƒν•œλ‹€.

(function () {
  'use strict';

  //SyntaxError: Duplicate parameter name not allowed in this context
  function foo(x, x) {
    return x + x;
  }
  console.log(foo(1, 2));
}());

βœ” with 문의 μ‚¬μš©

with문을 μ‚¬μš©ν•˜λ©΄ SyntaxErrorκ°€ λ°œμƒ.

with문은 μ „λ‹¬λœ 객체λ₯Ό μŠ€μ½”ν”„ 체인에 μΆ”κ°€ν•œλ‹€. with문은 λ™μΌν•œ 객체의 ν”„λ‘œνΌν‹°λ₯Ό λ°˜λ³΅ν•΄μ„œ μ‚¬μš©ν•  λ•Œ 객체 이름을 μƒλž΅ν•  수 μžˆμ–΄μ„œ μ½”λ“œκ°€ κ°„λ‹¨ν•΄μ§€λŠ” νš¨κ³Όκ°€ μžˆμ§€λ§Œ μ„±λŠ₯κ³Ό 가독성이 λ‚˜λΉ μ Έ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”κ²ƒμ΄ μ’‹λ‹€.

(function () {
  'use strict';

  // SyntaxError: Strict mode code may not include a with statement
  with({ x: 1 }) {
    console.log(x);
  }
}());

6.strict mode μ μš©μ— μ˜ν•œ λ³€ν™”

βœ” 일반 ν•¨μˆ˜μ˜ this

strict modeμ—μ„œ ν•¨μˆ˜λ₯Ό 일반 ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœν•˜λ©΄ this에 undefinedκ°€ 바인딩 μƒμ„±μž ν•¨μˆ˜κ°€ μ•„λ‹Œ 일반 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œλŠ” thisλ₯Ό μ‚¬μš©ν•  ν•„μš”κ°€ μ—†κΈ° λ•Œλ¬Έ. μ΄λ•Œ μ—λŸ¬λŠ” λ°œμƒν•˜μ§€ μ•ŠμŒ.

(function () {
  'use strict';
  
  function foo() {
    console.log(this); // undefined
  }
  foo();
  
  function Foo() {
    console.log(this); // Foo
  }
  new Foo();
}());

βœ” arguments 객체

strict modeμ—μ„œλŠ” λ§€κ°œλ³€μˆ˜μ— μ „λ‹¬λœ 인수λ₯Ό μž¬ν• λ‹Ήν•˜μ—¬ 변경해도 arguments 객체에 λ°˜μ˜λ˜μ§€ μ•ŠλŠ”λ‹€.

(function (a) {
  'use strict';
  // λ§€κ°œλ³€μˆ˜μ— μ „λ‹¬λœ 인수λ₯Ό μž¬ν• λ‹Ή ν•˜μ—¬ λ³€κ²½
  a = 2;
  
  // λ³€κ²½λœ μΈμˆ˜κ°€ arguments 객체에 λ°˜μ˜λ˜μ§€ μ•ŠλŠ”λ‹€.
  console.log(arguments) // { 0 : 1, length: 1 }
}(1));

0개의 λŒ“κΈ€