JavaScript 자주 하는 실수부터 콜백 지옥까지

13330 단어 frontendfrontend

패스트캠퍼스 강의를 정리한 내용입니다.
"The RED : 프론트엔드 Back to the Basics : 지속 가능한 코드작성과 성능 향상법 by 김태곤"

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

ES6

  • ECMAScript 6th edition 부터는 연도 표기
  • 2015년부터 해마다 새 명세가 갱신
  • 보통 'ES6'라고 하면 'ES6와 그 이후'를 의미

ESM으로의 전환

  • CommonJS, AMD가 ESM으로 전환
  • ESM
    • HTML5 표준에 포함됨
    • Node 12버전부터 ESM 방식 지원
    • Webpack, Rollup 같은 대다수 번들러의 기본 모듈 로딩 방식은 ESM
    • 별도 라이브러리가 필요한 다른 방식과 달리 ESM 방식은 웹 브라우저에서 네이티브로 지원
      → 아직은 브라우저 호환성 문제가 있으나 그럼에도 널리 사용될 것으로 전망
    • <script> 태그도 ESM을 지원함
      <script> 태그에서 type을 모듈로만 써두면 모듈 방식을 사용해서 스크립트 파일을 불러올 수 있음

한 때 잠깐 사용되었던 AMD 방식은 이제는 번들러의 영향으로 널리 사용되지 않지만, NodeJS의 기본 모듈 로딩 방식인 CommonJS와 ESM 방식은 아직도 널리 사용되고 있다.

자바스크립트 미래

  • 브라우저, Node 발전에 따라 babel과 같은 트랜스파일러의 필요성 하락
  • JS가 아닌 JS: TS, WebASM, Rust 등
    • TypeScript
      • 자바스크립트의 확장판
      • 강한 타입 설정으로 안전한 프로그래밍 가능
      • 실행 전 정적 분석을 통해 에러 탐지 가능
    • Deno
      • Rust(모질라에서 만든 언어)로 제작됨
    • WebASM(WebAssembly)
      • 자바스크립트 코드를 특별한 규칙과 코드로 작성하면 parser가 빠르게 인식하고 동작
  • 새로운 번들러 등장: Webpack의 독주는 언제까지?


어휘적 환경

Lexical Environment

정의

  • 변수나 함수 등의 식별자를 정의할 때 사용되는 명세
  • 중첩된 어휘적 환경에 기반하여 동작함
  • Environment Record와 outer 속성을 포함
    - outer는 자기 자신보다 밖에 있는 Lexical Environment를 참조하는데, global 보다 밖에 있는 것은 없으므로 global에서 outer는 항상 null

관련 문법

  • 함수 선언(Function declaration)
  • 블럭문(Block statement)
  • Try~Catch문의 Catch 절

종류

  • 전역 환경(global environment)
  • 모듈 환경(module environment)
  • 함수 환경(function environment)

실행 컨텍스트

Execution Context

정의

  • 자바스크립트 코드가 실행되는 환경
  • 모든 JS 코드는 실행 컨텍스트 내부에서 실행됨

종류

  • 전역 실행 컨텍스트(global execution context)
    • 모든 스크립트 코드는 전역 실행 컨텍스트 내에서 실행됨
  • 함수 실행 컨텍스트(functional execution context)
  • eval 실행 컨텍스트(eval function execution context)
    자바스크립트에 eval이라는 함수가 있는데 문자열로 된 자바스크립트 코드를 전달하면 그대로 실행되는 환경
    → 속도나 보안 등 단점이 많으므로 이 항목은 제외!

*실행 컨텍스트는 함수를 실행하면서 발생하고 함수 실행이 종료되면 사라짐


어휘적 범위

Lexical Scope

  • 같은 범위 혹은 그보다 안쪽의 코드에서 바깥 영역에는 접근할 수 있지만, 그 반대는 성립하지 않음
  • 어휘적 범위는 함수 선언, 블럭문(if, for, while), Try-Catch의 catch 절에서 구분됨
<script>
// 아래 코드 실행 시 Uncaught Reference 에러 발생
function hello() {
	{
    	const greeting = '안녕하세요';
    }
    console.log(greeting);
}
hello();
</script>

클로져

Closure

  • 처음 만들어질 때의 어휘적 범위를 그대로 유지한 함수
  • 어휘적 범위 바깥에서 해당 범위에 접근 가능
<script>
function hello() {
	const greeting = '안녕하세요';
    
    // 함수 객체를 반환    
    return function() {
    	console.log(greeting);
    };
}

// hello() 함수를 실행하면 hello() Execution Context가 만들어짐
// 전역 실행 컨텍스트에 반환된 함수 객체 저장
const say = hello();

say();
</script>

엄격한 모드

  • Strict mode
  • 문법과 런타임 동작을 모두 검사하여 에러 검출

참고: https://beomy.tistory.com/13

진입 방법

  • "use strict": 전역 영역, 함수 내 표기
  • ES2015 모듈 사용 (자동 적용)
    → Webpack 같은 번들러를 사용하면 자동으로 'use strict'가 추가됨

*Babel이나 번들러없이 Vanilla 자바스크립트를 사용시에는 직접 추가해서 엄격한 모드를 기본으로 사용하는 것을 추천

일반 모드와의 차이

  • 조용한 에러 대신 명시적 에러 발생
  • JS 엔진 최적화를 어렵게 하는 실수 방지
  • 향후 ES2015에 포함될 예약어/문법 대비
<script>
"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;   // 16진수
const octal = 020;const octal = 0o20;// ES2015의 8진수 표현 방식
console.log(octal);
</script>

엄격한 모드 외의 엄격함

  • JS의 이상한 동작은 독특한 형변환도 원인
  • 일치 연산자(===) 사용 습관화
  • 명시적 형변환 활용
<script>
// 일치 연산자를 사용하지 않은 경우

1 == 1				// → true
1 == '1'			// → true
1 == 2				// → false

'' == false			// → true
[] == false			// → true, []는 falsy 값도 아님
null == undefined	// → true



// 일치 연산자를 사용한 경우

1 === 1				// → true
1 === '1'			// → false
1 === 2				// → false

'' === false		// → false
[] === false		// → false
null === undefined	// → false

</script>

좋은 웹페이지 즐겨찾기