[The RED : 프론트엔드 Back to the Basics] 5. Javascript

posinity·2023년 6월 20일

1. 자바스크립트의 현재와 미래



별도 라이브러리가 필요한 다른 방식과 달리 ESM 방식은 웹 브라우저에서 네이티브로 지원한다. <script> 태그에서 type을 모듈로만 써두면 모듈 방
식을 사용해서 스크립트 파일을 불러올 수 있다. 브라우저 호환성 문제도 있어 아직 널리 사용하기는 어렵지만 점차 사용이 확대될 것이다.

WebAssembly

JS 코드를 특별한 규칙과 문법으로 작성하면 훨씬 빠르게 동작한다는 개념. 그 규칙이라는 게 가독성이 좋은 게 아니라서 직접 JS로 프로그래밍하기보다는 다른 언어를 통해 개발한 걸 JS로 변환하라는 의미. C/C++ 코드를 WASM으로 변환하는 Emscripten등이 있음.
한 케이스 스터디에 의하면 최적화 되지 않은 WASM은 9배, 최적화를 한 상태에서는 21배까지 빠르게 동작했다고 함. 이미 고사양 게임에 많이 사용되는 Unreal Engine이 WASM로 만들어지는 시대

사실 브라우저 환경의 JS는 특수한 몇몇 상황을 빼면 지금보다 굳이 더 빠를 필요가 없을 정도. JS의 병목 현상은 백엔드 애플리케이션이나 브라우저 자체에서 발생하는 경우가 많음. 혹은 파일의 크기나 캐시 정책 문제 등과 같이 언어 외적인 문제에서 많이 발생함. 따라서 일반적으로는 대단한 성능이 필요하지 않은데 물론 게임이나 그래픽 처리 등에는 속도가 많이 필요함. 따라서 WebAssembly는 이런 분야에 주로 사용되고 일반적인 UI 프로그래밍은 JS의 영역으로 그대로 남을 것이라 예상.

TypeScript

굉장히 빠른 속도로 성장하고 있는 언어. 2019년 기준 이미 GitHub에서 가장 인기있는 언어 6위에 랭크되었다. JS와 달리 강한 타입을 강제하므로 C,
Java와 같은 언어에서 출발한 분들은 오히려 더 편하게 느끼기도 하더라. 다만, TS는 어디까지나 Compile-to-JS 언어이다. 결국 브라우저나 Node.js 환경에서 실행하려면 JS로 변환되어야 한다는 것이다.
또한 TS는 JS의 확장판이다. 내부적인 동작은 어디까지나 JS의 규칙을 따른다. 그러니 먼저 JS를 공부하고 익숙해졌다 싶을 때쯤 TS로 영역을 확장해나가는
것을 추천한다.

참고 링크

2. 어휘적 환경


식별자 : 변수나 함수의 이름

global 바깥에 있는건 없음
outer : 나보다 밖에 있는 환경을 참조. 글로벌에서는 항상 null이 됌.

3. 실행 컨텍스트

eval 함수 : 문자열로 된 자바스크립트코드를 전달하면 실행되는 환경 -> 필요성이 없어 없다고 생각하기

8번 줄에서 함수 실행에 해당하는 EC가 발생. (함수를 실행했을 때 발생! -> 함수 실행 컨텍스트)

각 EC에는 몇 가지 상태 컴포넌트가 존재한다. 그 중에 가장 중요한 세가지.

  • Function : 함수 실행으로 만들어진 EC의 경우 함수 객체. 전역 실행 컨텍스트는 null
  • Lexical Environment : 실행되는 환경에 대한 정보
  • Variable Environment : EC가 초기화 될 때는 LE와 VE가 똑같음.

Lexical Environment와 Variable Environment에는 아까 살펴보았듯이 Environment Record와 outer라는 속성이 있음. ER에는 변수와 함수 등을 목록으로 저장하고 있어서 접근을 제어할 수 있음.

실행 컨텍스트가 이해가 안된다면 아래 글 참고!
JavaScript의 실행 컨텍스트

4. 어휘적 범위


5번째줄은 2~4번째 코드에 접근할 수 없다. -> 레퍼런스 에러 발생
중괄호가 있으면 블럭문이라고 보면 됌.

5. 클로져

클로져 : 함수와 함수가 선언된 어휘적 환경의 조합

코어 자바스크립트에서는 이렇게 정의함 : 어떤 함수 A에서 선언한 변수 a를 참조하는 내부 함수 B를 외부로 전달할 경우, A의 실행 컨텍스트가 종료된 이후에도 변수 a가 사라지지 않는 현상

  1. 9번째 줄에서 hello() 함수를 실행하면 hello() Execution Context가 만들어진다.

    함수를 실행할 때마다 실행 컨텍스트가 만들어짐

  2. 4번째 줄을 보면 함수 객체를 반환하고 있고 이 값은 9번째 줄에서 전역 실행 컨텍스트의 EC라는 값으로 저장되었다.
  3. 전역 컨텍스트의 say 변수에는 9번째 줄에서 만들어진 hello() 실행 컨텍스트 안의 함수가 저장되어 있다
  4. say 함수의 [Environment] 속성은 say() 실행 컨텍스트의 outer가 된다.
  5. 10번째 줄이 실행될 때 say 함수는 greeting 변수를 찾겠지만 현재 실행 컨텍스트에는 없다.
  6. 바깥 실행 컨텍스트에서 찾아야 하는데 이 경우 say() 실행 컨텍스트의 바깥 컨텍스트는 hello() 실행 컨텍스트가 된다.
  7. 콘솔에는 2번째 줄에 있던 "안녕하세요"라는 문자열이 출력될 것이다.

원래라면 hello()라는 실행 컨텍스트는 실행 후 사라져야 하나, 전역 컨텍스트의 say라는 값에 참조가 됐기 때문에 없애지 못하고 유지 -> 10번째 줄에서 실행 컨텍스트를 만들면서 다시 참조

6. 엄격한 모드

글로벌, 함수, ES2015 모듈. Webpack 같은 번들러를 사용한다면 자동으로 'use strict'를 추가해주기도 함.

엄격한 모드를 실행하면 막을 수 있는 에러

1. 선언하지 않은 변수에 값을 할당할 수 없음

str = "hello, world";

2.읽기 전용 전역 객체에 값을 할당하면 에러가 발생함.

일반 모드에서는 조용한 에러로 처리됨 (에러가 나타나지 않고 무시됌)

var undefined = 5;
var Infinity = 5;
NaN = "Wow";

3. 지울 수 없는 값을 지우려고 하면 에러가 발생함.

일반 모드에서는 조용한 에러로 처리됨

delete Object.prototype;

4. 함수 파라미터에 중복 이름을 사용할 수 없음.

function sum(a, a, c) {
  console.log(a + a + c);
}
sum(1, 2, 3);

5. ES5의 8진수 리터럴 사용 불가. (애초에 표준도 아니었음)

const hex = 0xff;
const octal = 020;
const octal = 0o20; // ES2015의 8진수 표현 방식
console.log(octal);

형변환

문제

정답

일치 연산자의 사용

트리플 이퀄스(===)를 기본으로 사용하자.
타입을 변환하는 것을 함수로 기록하고 비교하는 습관 들이기

7. 비동기


웹 페이지의 DOM을 읽어들인 후 코드를 실행하는 것도 비동기. 5초 후 콘솔에 문자열 하나 출력하는 것도 비동기. 사용자의 클릭 입력을 받아서 처리하는 것도 비동기. 여기엔 없지만 서버와 통신하는 것도 죄다 비동기로 처리된다.


여기서 중요한 것은 ui업데이트나 사용자 이벤트도 같은 스레드에서 처리된다는 것!
콜스택에서 어떤 함수가 너무 오랫동안 실행되고 있으면 이벤트루프가 메시지큐를 확인하지 않음
-> 화면 버벅임이 나타나는 것! ui가 동작하지 않기 때문.

함수 하나를 너무 오래걸리지 않도록 작은 단위로 쪼개라!

콜백 지옥

해결 방법

  1. "fail fast". 에러가 발생하거나 실패 조건에 도달했을 때 애플리케이션이나 함수를 빠르게 종료
    하는 방법.
  2. 별도 함수로 로직 분리. 익명 함수 부분을 별도 파일로 분리하는 걸 고려.
    files.forEach 부분 -> resizeSingleImage(),
    widths.forEach 부분 -> writeImageTo. 요건 arrow function으로도 바꿀 수 있겠다.
  3. 별도 파일로 모듈 분리. 만약 공통적으로 사용할 수 있는 부분이 있다면 다른 모듈로 분리해두는 것도 방법.

promise

  • 성공 -> 이행 / 실패 -> 거부
  • .then은 성공했을 때와 실패했을 때 둘다 사용할 수 있음. (첫번째 인자는 성공했을 때, 두번째 인자는 실패했을 때 함수를 전달)
  • 실패했을 때는 then의 두번째 인자로 전달하는 것보다 catch로 사용하는 것을 더 추천!!(좀 더 읽기 쉬움)
  • finally : 성공이든 실패든 무조건 처리해야 하는 것은 finally로 사용
  • Promise.resolve() : 무조건 성공인 promise를 반환함.
  • Promise.reject() : 무조건 실패인 promise를 반환함.
  • promise MDN 보기

async/await

업로드중..

8. 요약 정리

업로드중..

링크

Strict Mode 예제: https://codesandbox.io/s/i2yig?file=/app.js
[자바스크립트] 엄격 모드(한글): https://beomy.tistory.com/13

profile
문제를 해결하고 가치를 제공합니다

0개의 댓글