JS NORMAL | 프로토타입

chaen·2024년 1월 23일
0

JS Grammar

목록 보기
17/28
post-thumbnail

📘 자바스크립트의 클래스와 프로토타입 쉽게 이해하기

자바스크립트는 독특하게 클래스 기반과 함수형 둘 다 지원하는 유연한 언어입니다. 이 문서에서는 클래스, 프로토타입, 생성자 함수 등을 친절하게 설명하고, 클래스와 함수형 방식 비교도 함께 다룰게요!


✅ 1. 클래스 기반 언어란?

Java, Python, Ruby 같은 언어들은 전통적인 클래스 기반 객체지향 언어입니다.

비유하자면:

  • 클래스 = 붕어빵 틀, 사람이라는 설계도
  • 객체 = 붕어빵, 실제 사람 (나, 엄마, 친구 등)
  • 변수 = 각각의 상태 (이름, 나이 등)

예를 들어 Java에서는:

class Person {
  String name;
  int age;

  void introduce() {
    System.out.println("안녕하세요");
  }
}

이렇게 class로 설계도를 만들고, 그걸로 객체(인스턴스)를 만들죠.


✅ 2. 자바스크립트의 클래스와 프로토타입

자바스크립트도 객체지향 언어예요. 다만 원래는 클래스가 없고, 대신 프로토타입(Prototype) 이라는 독특한 방식으로 객체 간 상속을 구현했어요.

📌 ES6 이후에는 class 키워드가 도입되어 문법이 더 익숙하게 바뀌었지만, 내부적으로는 여전히 프로토타입 기반으로 동작해요.

참고: MDN - JavaScript 클래스


✅ 3. 프로토타입이란?

프로토타입은 객체가 물려받는 원형(DNA)입니다. 객체가 가진 속성이나 메서드가 없다면, 자바스크립트는 상위 원형(프로토타입)을 따라가며 찾습니다. 이것을 **프로토타입 체인(Prototype Chain)**이라고 해요.

예:

const arr = [1, 2, 3];
arr.sort(); // sort는 어디서 왔을까?

배열은 Array.prototype이라는 틀을 상속받고 있고, 그 안에 sort, push 등의 메서드가 정의돼 있어서 쓸 수 있는 거예요.


✅ 4. 생성자 함수와 객체 만들기

new 키워드를 이용하면 생성자 함수를 통해 객체를 만들 수 있어요.

function User(name, age) {
  this.name = name;
  this.age = age;
}

const u1 = new User("채원", 25);
  • User는 객체 설계도 역할을 해요.
  • new를 붙이면 새로운 객체가 만들어지고 this는 그 객체를 가리켜요.

User.prototype에 메서드를 추가하면, 모든 인스턴스에서 공유할 수 있어요.


✅ 5. prototype vs proto

  • prototype: 함수(특히 생성자 함수)에 붙는 속성으로, 인스턴스들이 참조하는 메서드나 속성을 정의하는 공간입니다.
  • __proto__: 실제 인스턴스 객체가 갖고 있는 숨겨진 링크. 자신의 부모 prototype을 참조합니다.

📌 __proto__는 오래된 방식이므로 Object.getPrototypeOf() 같은 표준 메서드를 사용하는 게 좋습니다.


✅ 6. 프로토타입 체인

const arr = [10, 20];
arr.toString(); // 어디서 왔을까?
  • arr → Array.prototype → Object.prototype → null
  • 이렇게 위로 위로 따라가며 원하는 속성이나 메서드를 찾아요.
  • 이 과정을 프로토타입 체인이라고 해요.

✅ 7. 프로토타입을 사용한 메모리 절약

function Person() {}
Person.prototype.eyes = 2;
Person.prototype.nose = 1;

const kim = new Person();
const park = new Person();
  • 공통 속성은 prototype에 정의하면 한 번만 저장되고, 모든 객체가 공유해서 메모리 효율적입니다.

✅ 8. 클래스 vs 함수형 객체 생성 비교

☑️ 클래스 기반 방식

class User {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  introduce() {
    return `안녕하세요, 저는 ${this.name}이고 ${this.age}살입니다.`;
  }
}

const user1 = new User("채원", 25);
console.log(user1.introduce());

☑️ 함수형 방식

const createUser = (name, age) => {
  const introduce = () => `안녕하세요, 저는 ${name}이고 ${age}살입니다.`;
  return { name, age, introduce };
};

const user2 = createUser("채원", 25);
console.log(user2.introduce());
항목클래스 방식함수형 방식
구조상태 + 메서드 결합함수로 객체 구성
메서드 저장 위치prototype 공유매번 새로 생성됨
메모리 효율좋음상대적으로 떨어짐
복잡한 앱유리함불리함 (확장 어려움)
간단한 구조과할 수 있음간결하고 빠름

✅ 9. 화살표 함수의 this 고정 특성

화살표 함수는 일반 함수와는 다르게 this를 자신이 정의된 시점의 외부 스코프에서 고정해 버립니다.

🔍 외부 스코프란?

여기서 말하는 "외부 스코프"는 화살표 함수가 만들어질 때 감싸고 있는 함수나 클래스, 혹은 전역 객체를 의미합니다.
예를 들어, 클래스의 constructor 안에서 화살표 함수를 만들면, 그 화살표 함수는 constructor 안의 this—즉 해당 클래스 인스턴스를 기억하게 됩니다.

일반 함수는 누가 호출하느냐에 따라 this가 바뀌지만, 화살표 함수는 "나는 처음 만들어졌을 때의 this만 쓸 거야!"라고 고정해 버리는 거예요.

📌 예시 비교

class Counter {
  constructor() {
    this.count = 0;
    setInterval(function () {
      this.count++; // ❌ 여기서 this는 Counter 인스턴스가 아님
    }, 1000);
  }
}

이 경우 일반 함수는 setInterval 내부에서 this가 window 또는 undefined를 가리키게 되어 this.count는 작동하지 않습니다.

화살표 함수로 바꾸면:

class Counter {
  constructor() {
    this.count = 0;
    setInterval(() => {
      this.count++; // ✅ this는 Counter 인스턴스를 기억함
    }, 1000);
  }
}

화살표 함수는 생성 시점의 외부 스코프, 즉 constructorthis를 기억하기 때문에, 이 안에서 this.count++가 잘 작동합니다.

💡 정리

  • 화살표 함수는 자신만의 this를 가지지 않고, 만들어질 당시의 외부 this를 기억합니다.
  • 이 특성 덕분에 콜백 함수나 비동기 처리 함수에서 this를 잃지 않고 사용할 수 있어요.
  • 하지만 클래스의 메서드는 보통 일반 함수(method() {})로 선언하는 것이 더 적절합니다. 이유는 this를 고정시키지 않고 동적으로 다룰 수 있기 때문입니다.

화살표 함수는 일반 함수와는 다르게 this를 자신이 정의된 시점의 외부 스코프에서 고정해 버립니다. 즉, 누가 호출하느냐에 따라 this가 바뀌는 일반 함수와 달리, 화살표 함수는 항상 태어난 환경의 this만 참조합니다.

📌 예시 비교

class Counter {
  constructor() {
    this.count = 0;
    setInterval(function () {
      this.count++; // ❌ this는 Counter 인스턴스가 아님
    }, 1000);
  }
}

이 경우 thissetInterval의 내부 컨텍스트를 가리키므로 this.countundefined가 됩니다.

같은 코드를 화살표 함수로 바꾸면:

class Counter {
  constructor() {
    this.count = 0;
    setInterval(() => {
      this.count++; // ✅ this는 Counter 인스턴스를 기억함
    }, 1000);
  }
}

이제는 thisCounter 인스턴스를 올바르게 가리켜 원하는 대로 동작합니다.

💡 정리

  • 화살표 함수는 자신만의 this를 가지지 않고, 외부 스코프의 this를 캡처합니다.
  • 콜백 함수, 이벤트 핸들러, 비동기 함수 내부에서 this를 유지해야 할 때 유용합니다.
  • 하지만 클래스의 메서드 정의에는 일반 함수가 더 적합한 경우가 많습니다 (의도치 않은 this 고정 방지).

✅ 정리 요약

개념설명
클래스객체를 만들기 위한 설계도 (ES6 이후 문법 도입)
생성자 함수class 없이 객체 만드는 방법 (전통적인 방식)
프로토타입상속과 메서드 공유를 위한 구조
프로토타입 체인속성 없을 때 상위 prototype에서 계속 탐색
클래스 vs 함수형상황에 따라 선택: 복잡함 ↔ 간결함

💡 결론: 자바스크립트는 객체지향도 가능하고 함수형도 가능해요.
필요에 따라 둘 중 하나를 선택하거나, 섞어서 사용하면 됩니다! 😄

0개의 댓글