본문 바로가기

항해99_10기/105일의 TIL & WIL

[20221112] scope & strict mode & module

  • 자바스크립트에서 scope (변수가 존재하는 범위)는 {} 블록과 function {} 함수 블록이 존재한다.
    • 종종 여러 자바스크립트 문서를 합치다 보면, 변수 충돌 문제가 발생하는데, 이때, 해결 방법으로 scope를 나눠줄 수 있다.
    • 하지만, 구 버전의 자바스크립트에서는 변수를 선언하기 위해 var 키워드를 사용했고, var의 경우, 함수 블록을 사용하는 경우에만 충돌을 막을 수 있음
    • 또, Babel 등과 같이 최신 버전의 자바스크립트를 구 버전의 스크립트로 변환해주는 트랜스파일러도 단순 {} 블록으로 함수 충돌을 막는 코드는 제대로 변환해주지 못함
    • 따라서, 변수 충돌 문제를 해결하기 위해 많은 경우, 함수 블록을 사용함 => 이때, 선언적 함수를 사용해 스크립트가 실행되면 해당 함수블록이 바로 호이스팅 되도록 만들어 줌
    • 같은 이름의 선언적 함수가 서로 다른 블록에서 선언된다면, 함수의 실행 흐름을 예측하는 것이 어려움 => 스크립트가 실행되어도 자동으로 호이스팅 되지 않는 익명함수가 더욱 안전한 옵션임
// 함수 블록을 사용해 변수명 충돌을 해결한 경우
<script>
    let pi = 3.14
    console.log(`파이 값은 ${pi} 이다.`);
</script>

<script>
    (function () {
        let pi = 3.141592;
        console.log(`파이 값은 ${pi} 이다.`);
    })()
</script>

// 파이 값은 3.14 이다.
// 파이 값은 3.141592 이다.


// 서로 다른 블록에서 같은 이름의 선언적 함수를 선언한 경우
<script>
  선언적함수();

  function 선언적함수() {
    console.log("1번째 선언적 함수");
  }
</script>

<script>
  function 선언적함수() {
    console.log("2번째 선언적 함수");
  } 
</script>

<script>
  선언적함수();
</script>

// 1번째 선언적 함수
// 2번째 선언적 함수

 

  • strict mode : 엄격모드는 자바스크립트가 오류를 어느정도 무시하고 넘어가는 것을 방지해주는 모드를 말한다. 
 

Strict mode - JavaScript | MDN

JavaScript's strict mode is a way to opt in to a restricted variant of JavaScript, thereby implicitly opting-out of "sloppy mode". Strict mode isn't just a subset: it intentionally has different semantics from normal code. Browsers not supporting strict mo

developer.mozilla.org

  • 스크립트 전역에 'use strict'를 선언하여 스크립트 전역에서 엄격모드를 사용할 수도 있고, 함수 블록 최상단에 선언을 해서 블록 단위로 사용할 수도 있다.
  • 자바스크립트는 점점 발전하고 있으므로, 엄격모드에 대한 변화도 공식문서를 통해 트래킹 하는 것이 중요하다.
  • 모듈을 사용하는 경우, 'use strict'를 선언하지 않아도, 자동으로 엄격모드가 시행된다.
    • 모듈이란 독립적이며, 재사용이 가능한 공개된 함수 단위의 코드 블럭을 말한다. 예를 들면, main.js에서 개발한 기능을 paymet.js와 login.js에서 불러다 사용하는 것이다.
    • 참고로, 모듈을 사용하려면, node.js의 버전이 13.2.0 이상이어야 한다.
 

Strict mode - JavaScript | MDN

JavaScript's strict mode is a way to opt in to a restricted variant of JavaScript, thereby implicitly opting-out of "sloppy mode". Strict mode isn't just a subset: it intentionally has different semantics from normal code. Browsers not supporting strict mo

developer.mozilla.org

 

 

JavaScript Modules – Explained with Examples

A module is a function or group of similar functions. They are grouped together within a file and contain the code to execute a specific task when called into a larger application. You create modules to better organize and structure your codebase. You can

www.freecodecamp.org

 

오늘 만난 에러

모듈을 사용해 보려고 test.js 파일에서 만든 함수를 'export {함수명}' 해보았다. 그리고 다른 스크립트에서 'import 함수명 from ./test.js'를 해 보았는데, 아래와 같은 에러 메시지를 확인했다.

더보기
Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.

에러를 해결하기 위해 프로젝트 폴더에 package.js 파일을 추가해주었다.

npm init -y

폴더에 생성된 package.js 파일에 '"type" : "module"'을 추가해 주었다.

{
  "name": "algorithm",
  "version": "1.0.0",
  "description": "",
  "main": "binary_search.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
    
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "type": "module"
}

 이후 다시 node.js를 통해 스크립트 파일을 실행해주니 모듈이 아주 잘 동작한다.

 

오늘의 실험

모듈을 사용하면 실제로 'use strict'를 선언하지 않아도 자동으로 엄격모드가 실행되는지 확인해보았다.

// test.js 파일에서 answer 변수 앞에 의도적으로 변수 타입을 선언하지 않았음

function returnFirstDecimal(n) {
  answer = [];
  while (n > 0) {
    answer.push(n % 10);
    n = Math.floor(n / 10);
  }
  return console.log(answer);
}

returnFirstDecimal(345);  // [5, 4, 3]

export {returnFirstDecimal}


// 다른 스크립트에서 모듈을 import해서 사용하면 아래와 같은 에러 메세지가 뜬다.
import { returnFirstDecimal } from "./test.js";

returnFirstDecimal(415);

/*
/test.js:2
  answer = [];
         ^

ReferenceError: answer is not defined
~~~
*/

다시 test.js 파일에서 answer 앞에 let을 선언해주고, 다른 스크립트에서 모듈을 불러와 실행해보면, 아래와 같이 결과 값이  잘 출력된다.

// test.js에서 answer앞에 let을 선언
function returnFirstDecimal(n) {
  let answer = [];
  while (n > 0) {
    answer.push(n % 10);
    n = Math.floor(n / 10);
  }
  return console.log(answer);
}

export { returnFirstDecimal };

//다른 스크립트에서 모듈을 불러와 실행
import { returnFirstDecimal } from "./test.js";

returnFirstDecimal(415);  // [ 5, 1, 4 ]