냅다 프로젝트로 던져서 자바스크립트보다 뷰를 먼저 배웠고 또 기초도 없이 리액트로 코딩해오길 수개월... 이렇게 뭣도 모를 수 없다 싶어, 모던 자바스크립트로 다시 차근차근 공부를 해보고 있다.
그리고 책에서 발견한 안 그래도 궁금했던 그 녀석.
MDN에서 뭐만 검색해도 나오던 바로 그 녀석.
[▲ MDN Array 설명서 목록 中]
바로 프로토타입
이 녀석을 알아보자.
MDN에 검색해보면
상속과 프로토타입 체인에 대한 링크를 추천해준다.
해당 문서에 의하면 자바스크립트는 클래스 기반 언어가 아닌 프로토타입 기반의 언어다. 객체는 [[Prototype]]이라는 은닉(private) 속성을 가진다.
라고 말하고 있고,
모던 자바스크립트 책에서는 자바스크립트는 프로토타입을 기반으로 상속을 구현한다.
고 한다.
즉, 프로토타입은 자바스크립트가 객체 지향 프로그래밍을 구현하는 데 사용되는 핵심 도구 중 하나이다.
※ 잠깐! 객체 지향 프로그래밍은?
프로그램을 명령어의 집합으로 보는 절차지향적 관점에서 벗어나 객체(독립적 단위)의 집합으로 표현하려는 프로그래밍 패러다임이다. 객체지향 프로그래밍 언어의 대표적 특징이 클래스, 상속 그리고 캡슐화 등이 있다.
또 MDN을 보다면 prototype이 작성된 메소드와 되어있지 않은 메소드를 마주하게 된다. 무슨 차이가 있고, 왜 대체 map
은 Array.prototype.map()
나와있는데 실제로 사용할 때는 prototype을 사용하지 않을까?
console에 객체를 한 번 출력해보면 어느정도 추측할 수 있다.
배열을 하나 생성하고, 출력해보면 하단에 [[Prototype]]
이 있는 걸 확인할 수 있다. 지금까지 흐린 눈 하고 살았던 그 녀석을 열어보면 어디선가 많이 봤던 메소드들이 등장한다.
MDN 설명서 목록에서 봤던 Array.prototype.map()
은 있고, Array.of()
는 없다!
메소드(method)는 크게 두 가지로 나뉜다.
1. 인스턴스 메소드(Instance Methods)
인스턴스 메서드는 객체(인스턴스)에 속하는 메서드로, 객체를 생성한 후에 호출된다.이러한 메서드는 객체의 상태를 변경하거나 해당 객체의 데이터와 작업을 수행하는 데 사용된다.
예를 들어, 배열 객체의 push() 메서드나 문자열 객체의 toUpperCase() 메서드가 인스턴스 메서드에 해당한다.
2. 정적 메서드(Static Methods)
정적 메서드는 클래스 또는 생성자 함수 자체에 속하는 메서드로, 객체 인스턴스를 생성하지 않고 호출된다.이러한 메서드는 주로 유틸리티 함수를 제공하거나 특정 클래스와 관련된 동작을 수행하는 데 사용된다.
예를 들어, Math 객체의 Math.sqrt() 메서드나 Array 클래스의 Array.of() 메서드가 정적 메서드에 해당한다.
prototype이 표기된 메서드는 인스턴스 메서드구나!
왜 실제로 사용할 때는 prototype을 쓰지 않을까?
정답: 알아서 찾아주니까!
prototype을 명시하지 않아도 프로토타입 체인을 활용하는 상황이라면 객체 자체에서 먼저 찾고, 그 다음에는 프로토타입 체인을 따라 부모 객체의 프로토타입에서 forEach를 찾게 된다.
※ 프로토타입 체인?
자바스크립트가 객체 간에 상속 관계를 구현하는 방식이다. 위의 이미지에서 생성한 배열 객체 arr는 자바스크립트 객체의 특성을 상속 받은 상태다.
🤔 그럼에도 prototype을 꼭 써야하는 상황은?
새로운 메서드나 속성을 정의할 때, 변경할 때 등등...
객체에 새로운 메서드나 속성을 동적으로 추가하려면 prototype을 사용해야 한다. 예를 들어, 모든 배열에 특정한 동작을 수행하는 새로운 메서드를 추가하려면 Array.prototype에 정의해야 한다.
하지만! 이럴 경우 기존 객체의 모든 인스턴스에 영향을 미친다.
따라서 정말 부득이하거나 필요한 상황이 아닌 경우 절대! 확장해서는 안 된다고 하니 참고하자 🥶