모던 자바스크립트 Deep Dive

모던 자바스크립트 Deep Dive 책을 읽게 된 계기와 함수, 스코프 체인, this, 실행 컨텍스트, 이터러블, 유사 배열 객체에 대해 자세히 알아봅니다.

책을 읽게 된 계기


실무에서 Typescript 와 Node.JS 을 사용하서 개발을 해 오며, 주로 Typescript 의 활용법과 백엔드 프레임워크 (express, NestJS) 공부하는 것에 집중해 왔다. Javascript 는 어느 정도 내용을 대부분 알고 있다고 생각했었는데, 스스로 내가 아직 많이 부족하구나 라고 느꼈던 사건이 있었다. Typescript 의 다음 코드를 트랜스파일링 한 후 생성된 Javascript 파일이 이해가 되지 않았다.

// person.ts
class Person {
  constructor(private readonly _name: string) {}

  async sayHello() {
    console.log(this._name);
  }
}

위의 Typescript 코드를 ES5 target 으로 트랜스파일하면

var Person = /** @class */ (function () {
    function Person(_name) {
        this._name = _name;
    }
    Person.prototype.sayHello = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                console.log(this._name);
                return [2 /*return*/];
            });
        });
    };
    return Person;
}());

위와 같은 javascript 코드가 생성된다. Javascript 에서는 class 도 function 이라는 사실은 대략적으로 알고 있었지만, 위의 Javascript 코드 대부분을 이해하지 못한다는 사실이 부끄러웠다. name 은 왜 this 에 저장되고, sayHello 는 왜 prototype 에 심기게 되는지조차 이해하지 못했었다. 또한 Person 은 익명 함수가 즉시 실행되는 형태로 변화하였는데, 이렇게 변환하는 데에서 얻는 이점이 무엇인지도 몰랐었다.

짧은 코드로 스스로 수많은 부족함을 느끼던 와중에, 기본기를 다시 다잡아야겠다는 결심을 하게 되었다. NodeJS 백엔드 개발자가 되게 전에 Javascript 개발자부터 되자 라는 마음으로 책을 골라서 천천히 읽기 시작했다. Javascript 가 쉬운 언어일 것이라는 나의 생각은 예상대로 완전히 틀렸다. 또한 이 무렵에, 임성묵님이 작성해 주신 재밌는 글을 읽게 되었다. (자바스크립트는 왜 프로토타입을 선택했을까 ?) 이 글 또한 Javascript 자체에 대해 깊게 이해하고 싶어하는 욕구를 한층 더 키워준 계기가 되었다.

이 글에서는 Javascript 가 어려웠던(익숙하지 않았던) 원인이 되었던 Javascript 의 특성들을 정리하고자 한다.




함수

Javascript 에서의 함수는 일급 객체로 취급되며, 이러한 점이 Javascript 를 강력하고 유연한 언어로 만들어 준다. 하지만, Javascript 에서 함수는 개발자들을 헷갈리게 하는 요소 중 하나이다. 함수는 그 자체로 알아야 할 내용이 많기도 하며, 스코프 체인, this, 실행 컨텍스트, 클래스와 복합적으로 이해해야 제대로 이해할 수 있다.

먼저 Javascript 의 함수는 크게 일반 함수, 메소드, 화살표 함수로 분류할 수 있다. 다음의 세 함수는 대부분의 개발자들에게 친숙한 문법일 것이다.

// 일반 함수
function sayHello() {
    console.log("hello");
}
// 메소드
const person = {
    sayHello() {
        console.log("hello");
    }
}
// 화살표 함수
const sayHello = () => console.log("hello");

위의 세 함수를 실행시키면 모두 동일한 결과값을 얻을 수 있다. 하지만 그렇다고 해서 위의 세 함수가 같은 것일까 ? 세 함수는 모두 동일한 기능을 지니지만, 세 함수는 큰 차이들을 지니고 있다.

  1. super 의 사용 여부 super 은 주로 객체지향 언어에서 찾아볼 수 있는 예약어이다. 주로 인스턴스가 자신이 속한 부모를 찾을 때 사용한다. super 은 메소드와 같이 사용할 수 있다. 주로 클래스 내에서 사용되지만, Javascript 에서는 클래스도 함수이므로, 다음과 같은 문법도 허용된다.
const parent = {
  name: "parent",
};

const child = {
  __proto__: parent,
  sayParentName() {
    console.log(super.name);
  },
};

child.sayParentName();

V8 엔진에서는 __proto__ 를 통해 부모 프로토타입으로 이동하므로, super.name 을 실행하면 parent 의 name 을 프린트하게 된다.




스코프 체인




this




실행 컨텍스트




이터러블, 유사 배열객체


목차

책을 읽게 된 계기 함수 스코프 체인 실행 컨텍스트 this 클로저 클래스 이터러블, 유사 배열 객체

이것도 읽어보세요