BangDori / woowa-typescript

우아한 타입스크립트 with 리액트 (우아한형제들 저) - 배달의민족 개발 사례로 살펴보는 우아한형제들의 타입스크립트와 리액트 활용법
2 stars 0 forks source link

[우아한 타입스크립트 with 리액트] 1.1 웹 개발의 역사 (1) #1

Open BangDori opened 11 months ago

BangDori commented 11 months ago

자바스크립트의 탄생

자바스크립트는 C, 자바와 유사한 기본 문법을 가지고 있으며 별로 유명하지 않던 객체 지향 언어인 셀프의 프로토타입 기반 상속 개념Lisp 계열 언어 중 하나인 스킴의 일급 함수 개념을 차용한 경량의 프로그래밍 언어였다. 브랜든 아이크는 초기에 자바스크립트를 웹 대응 언어로서 완벽한 해결책으로 제시하기보다는 빠르게 시장 반응을 확인할 수 있는 프로토타입 언어로 출시할 것을 목표로 하여 단 10일 만에 개발했다.

🤔 왜 프로토타입 언어였을까?

프로토타입 기반 언어는 클래스 기반 언어에서 상속을 사용하는 것과는 다르게, 객체를 원형 (프로토타입)으로 하는 복제 과정을 통해 객체의 동작 방식을 재사용할 수 있게 하는 것입니다.

image

프로토타입 기반 언어는 원형 객체를 복제하여 새로운 객체를 생성하는 언어를 의미하는데, 자바스크립트는 프로토타입 언어로서 복제가 아닌 링크를 통해 원형을 참조하는 방식을 채택하고 있습니다.

프로토타입 개발은 상대적으로 유연하고, 빠르게 변화하는 요구사항에 적응할 수 있습니다. 아이크는 JavaScript를 신속하게 개발하고, 실제 사용자의 피드백을 받아 개선할 수 있었습니다. (GPT)

당시 자바스크립트를 개발한 넷스케이프는 자사의 브라우저 내비게이터의 경쟁자로 나타난 마이크로소프트 사의 인터넷 익스플로러와 브라우저 점유율을 차지 하기 위한 "브라우저 전쟁" 을 벌이고 있었습니다.

이 배경에서 브라우저에 간단한 동적 요소를 추가하기 위해서 탄생한 것이 자바스크립트 입니다. 브라우저 점유율을 높이기 위해서는 내비게이터에서 작동하는 웹페이지들이 더 많아져야 했고, 그 말은 더 많은 사람들이 자바스크립트를 쉽게 사용할 수 있도록 유인했어야 했습니다.

프로토타입과 클래스의 비교

자바스크립트는 굉장히 쉽고 간단합니다. 이러한 간단함을 가장 잘 드러나는 것은 객체의 생성입니다.

자바와 자바스크립트를 비교해본다면, 자바에서 사람 객체를 만들 때 아래와 같은 코드를 작성하여야 합니다.

public static class Person {
    private final String name;
    private final String gender;
    public Person(final String name, final String gender) {
        this.name = name;
        this.gender = gender;
    }
}

반면, 자바스크립트에서 사람 객체를 생성하는 방식은 굉장히 단순했습니다.

const person = { name: 'jun', gender: 'male' }

한 눈에 보더라도 어떤 쪽이 초심자의 입장에서 더 간단한지 추측이 가능합니다. 물론 구조가 커지게 된다면 이러한 단순 비교는 큰 의미가 없을 것입니다. 하지만 쉬운이라는 단순한 기준을 놓고 보자면 자바스크립트가 압도적이라고 말할 수 있을 것입니다.

이러한 방식으로 객체를 생성하는 것이 가능한 이유가 프로토타입입니다. {}은 '객체 리터럴'로 이 방식으로 객체를 생성하면 new Object()로 객체를 생성하는 것과 유사하게 작동합니다. 빈 객체를 만든 뒤 해당 객체의 [[Prototype]] 속성이 내장 클래스인 Objectprototype 속성을 참조하도록 연결합니다.

자바스크립트가 이러한 단순함을 특징으로 가질 수 있는 것은 프로토타입 언어에서 코드가 재활용되는 방식이 위임(delegation) 이라는 개념으로 이루어지기 때문입니다.

클래스 기반 언어에서도 코드를 재활용하기 위해서 상속을 사용하지만, 상속은 이미 존재하는 클래스와 대부분 동일하지만 일부만 차이가 있는 새로운 클래스를 만드는 과정을 의미합니다.

그렇기에 상위의 클래스를 상속 받아 여러 하위 클래스를 생성하면 그 구조가 유사하기 때문에 예측 가능하고 안정적이라는 장점이 있습니다. 반면에 문제점은 생성된 클래스 사이의 결합성이 크기 때문에 한 부분에서의 변경이 미치는 영향의 범위가 넓다는 것입니다. 따라서 한 번 정해진 구조를 변경하는 것이 어렵습니다. 게다가 다중 상속이 불가능하다는 단점도 존재합니다.

프로토타입 기반의 언어는 코드를 재활용하기 위해 위임을 사용하여, 프로토타입을 참조하는 식으로 코드를 재활용 합니다. 그렇기 때문에 객체의 형태가 유연하여 속성의 추가 및 삭제가 자유롭다는 장점이 존재합니다. 물론 상대적으로 예측이 어렵고, 이로 인한 오류의 발생 가능성이 더 크다는 문제점이 존재합니다.

하지만 직접적이고 구조적인 유사성을 강제하지 않기 때문에 상대적으로 객체 사이의 결합성이 약합니다. 게다가 여러 객체의 프로토타입을 참조하는 방식으로 다중 상속의 구현이 가능하기 때문에 단순함을 확보할 수 있었습니다.

자바스크립트가 프로토타입을 기반으로 하게 된 결정적 이유는 바로 단순함

정리

클래스

장점

단점

프로토타입

장점

단점

출처

youngsu5582 commented 11 months ago

👍 내용이 깔끔하게 정리가 잘 되어 있습니다!

궁금한 점

  1. 다른 프로토타입 기반 언어들은 어떤게 있나요?

2.모든 같은 값을 넣은 객체는 동등 한지 궁금합니다!

const human= { name : 'youngsu' , gender :'male'};
const cloneHuman= { name : 'youngsu' , gender :'male'};

console.log(human===cloneHuman) // True or False?
  1. 참조를 통한 객체와 , new 생성을 통한 객체의 차이점이 있는지 궁금합니다!
    const object1 = { 'key':4};
    const object2 = new Object({'key':4});

    두가지 object 의 차이점이 있을까요??

2+3. 심화 질문 2번과 3번의 혼합으로 ,

const object1 = { 'key':4};
const object2 = new Object(object1);

console.log(object1===object2) // True or False?

해당 object1 과 object2는 동등한가요??

다시 한 번 , 깊은 내용 과 기초적인 내용을 생각하게 해준거 같아서 잘 보고 갑니다!!

BangDori commented 11 months ago

@youngsu5582 답변 감사합니다 👍

1. 다른 프로토타입 기반 언어들은 어떤게 있나요?

자바스크립트의 설계에 큰 영향을 미쳤던 언어는 Self도 있었지만, Lua도 있엇습니다.

Lua는 게임 개발과 임베디드 시스템에서 자주 사용되는 경량의 스크립트 언어로 자바스크립트에 영향을 준 만큼 자바스크립트 코드와 구성이 비슷한 것을 확인할 수 있습니다.

school = { name = nil, id = nil, locale = "seoul" } // nil = null

school.name = "eli"
school.id = 4

print(school.name)
print(school.locale)

앞서 루아가 게임 개발에 자주 사용되어 졌다고 말했는데, 앵그리 버드, 월드 오브 워크래프트 그리고 로블록스에서는 거의 모든 시스템이 루아로 이루어져 있습니다.

2.모든 같은 값을 넣은 객체는 동등 한지 궁금합니다!

const human= { name : 'youngsu' , gender :'male' };
const cloneHuman= { name : 'youngsu' , gender :'male' };

console.log(human===cloneHuman) // False

위 경우에는, human 객체를 cloneHuman 객체에 할당하는 것이 아닌 human 프로토타입과 cloneHuman 객체가 각각 생성되었기 때문에 각자 메모리상에서 다른 주소를 잡고 있어서 동등하지 않습니다.

하지만 아래와 같이 작성되어 있다면, 프로토타입을 복사하여 체인으로 연결되기 때문에 동일한 메모리 주소를 참조해 동등하다고 볼 수 있을 것 같습니다!

const human= { name : 'youngsu' , gender :'male' };
const cloneHuman= human;

console.log(human===cloneHuman) // True

3. 참조를 통한 객체와 , new 생성을 통한 객체의 차이점이 있는지 궁금합니다!

const object1 = { 'key':4};
const object2 = new Object({'key':4});

object1은 객체 리터럴을 이용해서, object2new Object를 이용하여 객체를 생성하고 있습니다. 두 object를 콘솔에 찍어보면 아래와 같이 내부적으로 동일하게 동작하는 것을 확인할 수 있습니다.

두 방법의 경우에는 객체를 생성하는 방법이 다를 뿐 동일한 객체를 생성합니다. 하지만 airbnb에서 제공하는 자바스크립트 스타일 가이드를 확인해보면 가독성측면에서 객체 리터럴 방식을 권고하는 것을 확인할 수 있습니다.

뿐만 아니라 퍼포먼스를 비교해도 객체 리터럴이 성능이 더 좋게 나오는 것을 확인할 수 있습니다. 그 이유는 new 키워드가 constructor 함수를 호출하여 객체를 생성하기 때문입니다.

자바스크립트에서 생성자 함수를 통해 객체를 생성하게 되면

  1. this 값 초기화
  2. arguments 초기화
  3. 실행 컨텍스트의 스코프 체인 계산

등의 많은 부가 작업을 합니다.

반면 객체 리터럴의 경우 constructor 함수 호출이라는 오버헤드 없이 한번에 객체를 생성하기 때문에 new Object() 보다 상대적으로 적은 오버헤드를 가집니다.

4. 해당 object1 과 object2는 동등한가요??

const object1 = { 'key':4};
const object2 = new Object(object1);

console.log(object1===object2) // True

위 코드에서 object1object2는 프로토체입으로 연결된 것이기 때문에 object1object2 객체는 동등합니다.

출처