FoO의 개발 블로그

[JS 개념정리 1] script 태그 속성, ES6 module, strict mode, 화살표함수 본문

Programming/FE

[JS 개념정리 1] script 태그 속성, ES6 module, strict mode, 화살표함수

FoO__511 2024. 6. 30. 20:38

항상 Next.js에서 자동으로 설정해주는 환경을 쓰다보니 기초적인 개념이 확고하지 않아 정리하고 간다.

 

Script 태그의 속성들

1. 기본(속성 없음)

<script src="script.js"></script>
  • HTML 파싱을 중단하고 스크립트를 즉시 다운로드 및 실행
  • 스크립트 실행이 완료될 때까지 HTML 파싱이 재개되지 않음

2. async 속성

<script src="script.js" async></script>
  • 스크립트를 비동기적으로 다운로드
  • HTML 파싱과 병렬로 다운로드 진행
  • 다운로드가 완료되면 HTML 파싱을 중단하고 즉시 스크립트를 실행
  • 여러 스크립트가 있을 경우 다운로드 완료 순서대로 실행

3. defer 속성

<script src="script.js" defer></script>
  • 스크립트를 비동기적으로 다운로드
  • HTML 파싱과 병렬로 다운로드 진행
  • HTML 파싱이 완료된 후에 스크립트 실행
  • 여러 스크립트가 있을 경우 HTML에 작성된 순서대로 실행

4. type="module" 속성

<script type="module" src="script.js"></script>
  • 스크립트를 ES6 모듈로 취급
  • 기본적으로 defer 속성과 유사하게 동작
  • strict mode 자동으로 적용

 

일반 스크립트과 ES6 모듈의 차이

1. 스코프

  • 일반 스크립트: 전역 스코프에서 실행
  • ES6 모듈: 모듈 스코프에서 실행, 전역 스코프와 분리

2. this 바인딩

  • 일반 스크립트: 최상위 레벨의 this = 전역 객체(브라우저에서는 window)
  • ES6 모듈: 최상위 레벨의 this = undefined

3. strict mode

  • 일반 스크립트: 기본적으로 non-strict mode. 'use strict'를 명시해야 strict mode 적용.
  • ES6 모듈: 항상 strict mode로 실행됩니다.

4. 변수 선언

  • 일반 스크립트: var로 선언된 변수는 전역 객체의 속성이 됨.
  • ES6 모듈: var, let, const로 선언된 변수는 모듈 스코프 내에 존재

5. import / export

  • 일반 스크립트: import/export 문을 사용할 수 없음.
  • ES6 모듈: import와 export 문을 사용하여 모듈 간 코드를 공유 가능

6. 실행 시점

  • 일반 스크립트: 기본적으로 HTML 파싱을 차단하고 즉시 실행 (async나 defer 속성이 없는 경우).
  • ES6 모듈: 기본적으로 defer 속성처럼 동작하여 HTML 파싱 후 실행

7. 중복 실행 방지

  • 일반 스크립트: 같은 스크립트를 여러 번 로드하면 여러 번 실행
  • ES6 모듈: 같은 모듈을 여러 번 임포트해도 한 번만 실행

8. CORS(Cross-Origin Resource Sharing)

  • 일반 스크립트: 기본적으로 CORS 제한이 없음.
  • ES6 모듈: 기본적으로 CORS 정책을 따름. 다른 출처의 모듈을 로드할 때 적절한 CORS 헤더가 필요.

 

위 특징들로 ES6 모듈은 더 안전하고 예측 가능한 코드 실행 환경을 제공하며, 대규모 애플리케이션에서 코드 구조화와 관리에 유리하다.

 

 

Strict mode

strict mode는 JavaScript에서 더 엄격한 구문 규칙과 에러 검사를 적용하는 특별한 실행 모드이다. ECMAScript 5에서 도입되었으며, 코드의 안정성을 높이고 잠재적인 오류를 줄이는 데 도움을 준다.

 

주요 특징:

  1. 선언되지 않은 변수 사용 금지
    • 일반 모드: 선언되지 않은 변수에 값을 할당하면 자동으로 전역 변수가 생성
    • strict 모드: ReferenceError를 발생
  2. 삭제 불가능한 속성 삭제 시 에러
    • 일반 모드: 실패 시 무시
    • strict 모드: TypeError 발생
  3. 함수 매개변수 이름 중복 금지
    • 일반 모드: 중복 허용
    • strict 모드: SyntaxError 발생
  4. 8진수 리터럴 사용 금지
    • 일반 모드: 0으로 시작하는 숫자를 8진수로 해석
    • strict 모드: SyntaxError 발생
  5. with 문 사용 금지
    • strict 모드: with 문 사용 시 SyntaxError 발생
  6. eval의 새로운 변수 생성 제한
    • strict 모드: eval()은 자체 스코프 내에서만 새 변수를 생성
  7. this 값의 변경
    • 일반 모드: 함수를 일반 호출할 때 this = 전역 객체
    • strict 모드: 함수를 일반 호출할 때 this =undefined

 

7. this 값의 변경 부연 설명

 

JavaScript에서 this의 값은 함수가 어떻게 호출되었는지에 따라 결정된다. strict mode와 non-strict mode에서 this의 동작은 특히 함수를 일반적으로 호출할 때 차이가 있다.

 

일반모드

일반 모드에서 함수를 단순히 호출할 때, this는 전역 객체를 가리킨다.

function showThis() {
  console.log(this);
}

showThis(); // 브라우저에서는 window 객체, Node.js에서는 global 객체

 

이는 의도치않게 전역 객체를 수정하는 실수를 유발할 수 있다.

 

strict mode

strict mode에서 같은 방식으로 함수를 호출하면, this는 undefine가 된다.

"use strict";

function showThis() {
  console.log(this);
}

showThis(); // undefined

 

 

메서드 호출

객체의 메서드에서 this를 호출할 때는 strict mode 여부와 관련 없이 객체를 반환한다.

"use strict";

let obj = {
  method: function() {
    console.log(this);
  }
};

obj.method(); // obj

 

생성자 함수

new 키워드로 생성자 함수를 호출하면 strict mode와 관계없이 해당 함수를 반환한다.

"use strict";

function Constructor() {
  console.log(this);
}

new Constructor(); // Constructor {}

 

call, apply, bind 메서드

위 메서드들을 사용할 때도 strict mode와 관계없이 동일하게 동작한다.

"use strict";

function showThis() {
  console.log(this);
}

showThis.call({a: 1}); // {a: 1}
showThis.apply({b: 2}); // {b: 2}
let boundFunction = showThis.bind({c: 3});
boundFunction(); // {c: 3}

 

이런 차이로 인해 strict mode에서 함수 내부의 this를 사용할 때 주의해야 한다. 

번외로, 콜백 함수나 내부 함수에서 외부 컨텍스트의 this를 참조하려면 화살표 함수(프로토타입을 생성하지 않음)를 사용하거나 this를 별도의 변수에 저장하는 등 처리가 필요하다.

 

strict mode 활성화 방법

"use strict";

// 이후의 코드는 strict mode에서 실행

 

또는 함수 내에서만 적용할 수도 있다.

function strictFunction() {
    "use strict";
    // 이 함수 내부만 strict mode
}

 

 

화살표 함수와 일반 함수의 차이

구문에 대한 설명은 생략한다.

 

1. this 바인딩

 

  • 일반 함수: 자신만의 this를 가지며, 호출 방식에 따라 동적으로 결정.
  • 화살표 함수: 자신의 this를 가지지 않고, 외부 스코프의 this를 그대로 사용 (렉시컬 this).

 

2. arguments 객체

 

  • 일반 함수: arguments 객체를  가짐.
  • 화살표 함수: arguments 객체가 없음. 대신 rest 파라미터를 사용 가능.

arguments 객체는 함수에 전달된 모든 인수들을 포함하는 함수 내부에서 사용할 수 있는 특별한 객체이다. 

예:

function exampleFunc() {
    console.log(arguments.length);  // 인수의 개수
    console.log(arguments[0]);      // 첫 번째 인수
    console.log(arguments[1]);      // 두 번째 인수
    
    // arguments 객체를 배열로 변환
    const args = Array.from(arguments);
    // 또는
    // const args = [...arguments];
}

exampleFunc(1, 'hello', true);
// 출력:
// 3
// 1
// hello

 

 

가변 인수 함수를 구현할 때 사용할 수 있다. 

 

현대 javascript는 이렇게 쓴다. (나머지 매개변수)

function modernFunc(...args) {
    console.log(args.length);
    console.log(args[0]);
    
    // args는 이미 배열이므로 배열 메서드를 직접 사용할 수 있음
    args.forEach(arg => console.log(arg));
}

 

3. 생성자 함수

 

  • 일반 함수: new 키워드로 생성자 함수로 사용 가능.
  • 화살표 함수: 생성자 함수로 사용할 수 없음 (TypeError 발생).

 

4. prototype 속성

 

  • 일반 함수: prototype 속성.
  • 화살표 함수: prototype 속성이 없음.

 

5. 메서드 정의

 

  • 일반 함수: 객체의 메서드로 정의할 때 function 키워드 생략 가능.
  • 화살표 함수: 객체의 메서드로 사용 시 주의가 필요 (this가 예상과 다를 수 있기 때문).

 

6. yield 키워드

 

  • 일반 함수: 제너레이터 함수에서 yield 키워드 사용 가능.
  • 화살표 함수: yield 키워드를 사용 못함.

 

7. 암시적 반환

 

  • 일반 함수: return 문을 명시적으로 사용해야 함.
  • 화살표 함수: 단일 표현식의 경우 중괄호와 return 키워드 생략 가능.