본문 바로가기
경일/Javascript

[Javascript] 메서드와 프로토타입

by dev_kong 2022. 1. 6.
728x90
728x90

0.목차

1. 개요

2. 메서드

3. 프로토타입

 

1.개요

우린 코드를 짜면서 정말 많은 메서드들을 사용한다.

메서드 없는 코딩을 상상하면 정말 끔찍하다.

너무나 소중한 메서드들...

메서드의 종류는 MDN한테 물어보고,

이번엔 메서드와 메서드의 깐부 프로토타입에 대해 조금 정리해보려한다.

2.메서드

2-1. 메서드란

메서드는 함수다.

근데 그냥 함수가 아니고,

객체에 들어있는 함수다.

이거 이상의 설명은 없을 듯..?

2-2. 메서드 만들기

그럼 직접 만들어 보자.

const kong = {
  age: 29,

  introduce: function () {
    console.log(`I'm ${this.age}years old`);
  },
};

 

kong이라는 object를 만들고 

age의 value에는 29을,

introduce의 value에는 함수를 넣어줬다.

 

근데 이건 옛날방법.

es6에 추가된 method shorthand를 이용하면 좀 더 간결하게 만들 수 있다.

 

const kong = {
  age: 29,

  introduce() {
    console.log(`I'm ${this.age}years old`);
  },
};

 

메서드를 실행하는 방법은 객체의 프로퍼티에 접근하는 방법과,

함수를 호출하는 방법을 섞어서 쓰면 된다.

 

객체의 프로퍼티에 접근

const kong = {
  age: 29,

  introduce() {
    console.log(`I'm ${this.age}years old`);
  },
};

console.log(kong.age); // 29

 

함수호출

function sum(a, b) {
  console.log(a + b);
}

sum(1, 2); //3

 

메서드호출

const kong = {
  age: 29,

  introduce() {
    console.log(`I'm ${this.age}years old`);
  },
};

kong.introduce(); // 29

 

혹시나 this를 모르겠다면...

https://kong-dev.tistory.com/110

 

[Javascript] this 동적 바인딩

0.목차 1. 개요 2. 메소드 생성 3. 메소드 호출 4. this 바인딩 1. 개요 수업에서 객체를 다뤘다. 혼자 객체도 만들어보고 메소드도 만들어보고 메소드로 property 참조하고 이것저것 해보다가, 어느 순

kong-dev.tistory.com

참고 정도는 될지도..

2-2. 나는 메서드를 만든적이 없는데..?

우리가 배열을 가지고 이런저런 코드를 작성할 때,

많은 메서드들을 쓴다.(filter, map, reverse, sort, reduce, push, pop................ 겁나 많다.)

push 메서드를 한번 사용해 보자.

const arr = [1, 2, 3];
arr.push(4);
console.log(arr); //[1,2,3,4]

아주 잘 된다.

근데 잠깐만.. 뭐지..? 싶다면 천재임..ㅇㅇ

 

이상한 점이 한가지 눈에 보인다.

어.. 배열이 객체라서 메서드가 사용되는 건 알겠어....

근데 나는 내가 만든 arr에 push 라는 메서드를 만들어 준 적이 없는데..?

어떻게 push라는 메서드를 쓸 수 있는거지..?

 

이 의문을 해소해줄 개념이 바로 프로토타입이다.

3. 프로토타입

3-1. 프로토타입이란

Javascript 를 공부하는 사람이라면 한번쯤,

단 한번쯤은 어디선가 프로토타입이란 단어를 들어본 적이 있을거다.

"프로토타입은 자바스크립트에서 상속을 가능하게 하기 위한 방법이다."

재밌게 읽은 아티클에서 나온 문장이다.

이 아티클의 저자는 저 문장을 정답이 아닌 결론 이라고 했지만,

난 저 문장을 읽었을 때, 저거만큼 프로토타입을 간결하고 명확하게 설명할 수 있을까 싶었다.

 

3-2. 상속

상속? 그거 뭐 물려 받고 그런거 아닌가?

정확하다. 상속은 물려 받는거다.

조금 더 정확하게 말하자면 자식이 부모에게 물려받는 거다.

이 물려주고 물려 받는 걸 가능하게 하는게 프로토타입이다.

상속의 예시를 코드를 통해서 보자.

 

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

const user1 = new User('kong', '29');

console.log(user1); // User { name: 'kong', age: '29' }

 

class 생성자 함수 User를 이용해 user1 이라는 인스턴스객체를 만들었다.

상속의 개념을 이해하기 위해,

생성자 함수 User의 prototype에 프로퍼티에 새로운 프로퍼티를 추가해 보겠다.

(prototype 프로퍼티는 함수객체만 갖고 있는 프로퍼티이다.)

 

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

const user1 = new User('kong', '29');

User.prototype.hometown = 'Busan';

console.log(user1); // User { name: 'kong', age: '29' }

console.log(user1.hometown); //Busan

 

User의 prototype 프로퍼티에 hometown이라는 키를 추가하고 value로는 'Busan'을 할당해주었다.

user1의 객체에 추가된 프로퍼티가 아니므로 당연하게도 user1 의 프로퍼티에는 변화가 없다.

하지만, user1에서 hometown이라는 키를 가진 프로퍼티에 접근을 하자,

User의 prototype 프로퍼티에 추가해준 프로퍼티의 value인 Busan이 참조되었다.

 

위의 예시를 통해 상속을 정리해보자면,

객체의 특정 프로퍼티에 접근하려 할 때,

객체에 접근한 프로퍼티가 있다면 객체내부에서 탐색을 멈추지만,

만일 객체 내부에서 접근하려는 프로퍼티를 발견하지 못했다면,

프로토타입체인 상의 상위(=부모/ 조상..?) 객체에서 탐색하여 해당 프로퍼티가 존재한다면,

마치 자신의 프로퍼티인양 사용하는 것을 의미한다.

그리고 이것을 가능하게 하는 것이 프로토타입이다.

 

 

3-3. 프로토타입체인

또 이상한 단어가 하나 등장했다.

프로토타입체인 이라는 친군데,

음 스코프체인을 이해하고 있다면 이해가 조금 쉬울 지도 모르겠다.

원리는 쌩판 다르지만, 얼추 엇비슷한 개념이다.

 

프로토타입체인을 설명하기 전에,

[[prototype]]이란 아이를 알아야한다.

[[prototype]]이란 내부슬롯 중 하나이며,

자바스크립트에 존재하는 모오오오오든 객체는 [[prototype]]이란 내부슬롯을 갖고있고,

이 [[prototype]]은 상속을 구현하는 프로토타입 객체를 가리킨다.

 

그리고 기본적으로 자바스크립트는 내부슬롯에 접근하는 것을 불가능하게 만들어졌다.

하지만 [[prototype]]에는 간접적으로 접근 할 수 있는 방법이 있는데,

그게 __proto__ 라는 아이이다.

 

__proto__라는 아이는 내부슬롯인 [[prototype]]에 접근할수있고, 변경도 해줄수 있는아이다!

프로토타입체인의 개념을 확인해보기 위해 

class 생성자 함수로 user2, user3 인스턴스 객체를 생성하고,

user3의 [[prototype]] 을 user2 로,

user2의 [[prototype]] 을 user1 로,

만들어 보겠다.

 

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

const user1 = new User('kong', '29');
const user2 = new User('bean', '18');
const user3 = new User('pea', '54');

user3.__proto__ = user2;
user2.__proto__ = user1;

user1.hometown = 'Busan';

console.log(user1); // User { name: 'kong', age: '29', hometown:'Busan' }
console.log(user2); // User { name: 'bean', age: '18' }
console.log(user3); // User { name: 'pea', age: '54' }

console.log(user3.hometown); //Busan

 

위에서 말한 작업들을 한 뒤,

user1 에다가 hometown: 'Busan' 이란 프로퍼티를 추가해주었다.

그리고 user3.homtown을 출력해보니 'Busan' 이 출력되었다.

 

이게 어떻게 된거냐면

user3 에서 hometown을 찾아봤지만 없다.

없으니까 user3의 프로토타입인 user2에서 hometown을 찾아본다.

하지만 마찬가지로 없다.

없으니까 user2의 프로토타입인 user1에서 hometown을 찾아본다.

user1은 hometown을 갖고 있다.

그러니까 user3는 user1의 hometown을 상속받아 제것인양 출력했다.

 

이 과정을 프로토타입체인을 따라 검색했다. 라고 할 수 있다.

여기까지 왔다면 굉장한 일을 해낸거다.

진짜 다왔다.

 

조오금만 더하면 된다.

프로토타입체인이 뭔지 개념을 잡았으니까,

이제 내가 만든 객체, 배열에서 어떻게 메서드가 실행되는지 짧고간략하게 설명할 수 있다.

 

const myArr = [2, 1, 4, 5, 3];
myArr.sort();
console.log(myArr); //[ 1, 2, 3, 4, 5 ]

myArr에서 sort라는 메서드를 실행했다.

프로토타입체인을 따라 myArr의 프로토타입인 Array 객체에서

sort라는 메서드를 발견한 뒤,

그것을 제 것 인양 사용한 것이다!

 

와 고작 4줄의 문장을 이해하기 위해 굉장히 먼길을 돌아돌아돌아왔다.

하지만 프로토타입의 개념을 모른채로 자바스크립트를 사용한다는건,

수박겉핥기가 아닐까... 라는 생각이 든다.

 

 

여기까지 와서 한가지 의문이 든다면 진짜진짜 천재다.

ㅇㅋㅇㅋ 이해했음 근데..

함수도, 배열도, 객체도 객체잖어..

근데 string은..? string은 premitive 인데..? 왜?

메서드가 작동되는거지?

 

ㅎㅎㅎ래퍼객체의 개념을 알아야하는데..

이건.. 다음에!

다음에 정리할거다. 언젠가는..

728x90
728x90

댓글