프로토타입이 무엇인가... 콘솔에서 많이 봤는데. 무언가 중요한 것이라는 건 알겠다.
이리저리 돌아다니자니 시간만 많이 걸릴 것 같아 내 기준 가장 믿음직한 사이트에서 찾아보기로 했다.
모든 자바스크립트 객체는 프로토타입으로부터 속성(프로퍼티)과 메소드를 상속받습니다.
모든 객체가 프로토타입으로부터 상속받는다고 한다. 그래서 결국 그 프로토타입이란 것이 무엇이지?
예시
function Person(first, last, age, eyecolor) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eyecolor; } const myFather = new Person("John", "Doe", 50, "blue"); const myMother = new Person("Sally", "Rally", 48, "green");우리는 또한 이미 존재하는 객체 생성자에 새로운 속성을 추가할 수 없다는 것도 배웠습니다.
예시
Person.nationality = "English";새로운 속성을 생성자에 추가하려면, 생성자 함수에 다시 추가를 해주어야 합니다.
위와 같은 코드를 더해봤자 myFather이나 myMother, 아니 Person에조차 nationality는 추가되지 않는다.
예시
function Person(first, last, age, eyecolor) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eyecolor; this.nationality = "English"; }
이런 식으로 함수 자체를 고쳐야 한다면 얼마나 번거롭겠는가?
모든 자바스크립트 객체는 프로토타입으로부터 속성(프로퍼티)과 메소드를 상속받는다.
Date오브젝트는Date.property로부터 상속받습니다.Array오브젝트는Array.prototype으로부터 상속받습니다.Person오브젝트는Person.prototype으로부터 상속받습니다.
Object.prototype은 prototpye 상속 체인의 가장 위에 있습니다.
Date오브젝트,Array오브젝트,Person오브젝트는Object.prototype으로부터 상속받습니다.
이미 존재하는 모든 유형의 객체에 새로운 속성이나 메소드를 추가하고 싶을 때가 있습니다.
객체 생성자에 새로운 속성이나 메소드를 추가하고 싶을 때도 있습니다.
예시
function Person(first, last, age, eyecolor) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eyecolor; } Person.prototype.nationality = "English";자바스크립트의
prototype속성은 새로운 속성을 객체 생성자에 추가시킬 수 있습니다.
예시
function Person(first, last, age, eyecolor) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eyecolor; } Person.prototype.name = function() { return this.firstName + " " + this.lastName; };자바스크립트의
prototype속성은 또한 새로운 메소드를 객체 생성자에 추가시킬 수 있습니다.
결론적으로 말하자면 prototype은 객체나 객체 생성자에 새로운 속성이나 메소드를 추가하고 싶을 때 사용되는 것인가?
뭔가 시원하지 않아서.. mdn에서 조금 더 찾아보았다.
prototype은 자바스크립트 객체가 서로 상속하는 메커니즘입니다.
아까 w3school과 크게 다를 것 없는 설명이다. 밑 부분을 더 읽어보았다.
const myObject = { city: "Madrid", greet() { console.log(`Greetings from ${this.city}`); }, }; myObject.greet(); // Greetings from Madrid이건
city라는 하나의 데이터 속성과greet()라는 하나의 메소드를 가진 객체입니다.만약 콘솔에
myObject.와 같이 객체의 이름 마지막에 온점을 찍는다면 콘솔은 사용 가능한 속성들을 띄워줄 것입니다. 그곳엔city와greet이 있긴 하지만, 다른 많은 속성들도 있습니다!__defineGetter__ __defineSetter__ __lookupGetter__ __lookupSetter__ __proto__ city constructor greet hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf그것들 중 하나에 접근하여 봅시다.
myObject.toString(); // "[object Object]"잘 동작합니다. (심지어
toString()이 무엇인지 정확하게 모름에도 불구하고,)
다른 추가속성은 무엇이며, 어디서 왔을까요?
자바스크립트의 모든 객체는 빌트인 속성(built-in property), 즉 프로토타입을 가지고 있습니다. 프로토타입은 그 자체로 객체이므로, 프로토타입 또한 그것만의 프로토타입을 가지고 있습니다. 그것을 프로토타입 체인이라고 부릅니다. 체인은 그것의 프로토타입이
null값을 가질 때 끝납니다.
당신이 객체의 속성에 접근하려 했는데, 만약 속성을 객체 자체에서 찾을 수 없을 때 프로토타입에서 검색합니다. 만약 속성을 여전히 찾을 수 없을때 프로토타입의 프로토타입에서 검색하고, 속성을 찾거나 프로토타입의 끝까지 검색합니다. 이 경우
undefined를 반환합니다.
그리하여
myObject.toString()을 호출한다면:
myObject내에서toString을 찾습니다.- 찾지 못한다면,
myObject내에서toString을 찾습니다.- 만약 그곳에 있다면, 반환합니다.
myObject의 프로토타입이 무엇일까요? 우리는 함수Object.getPrototypeOf()를 통해 찾을 수 있습니다.Object.getPrototypeOf(myObject); // Object { }
이것은
Object.prototype이라 불립니다. 그리고 가장 기본적인 프로토타입입니다. 모든 객체가 기본으로 가지고 있지요.Object.prototype의 프로토타입은null입니다. 그래서 이것은 프로토타입 체인의 마지막입니다.

하지만 모든 객체의 프로토타입이
Object.prototype인 것은 아닙니다.const myDate = new Date(); let object = myDate; do { object = Object.getPrototypeOf(object); console.log(object); } while (object); // Date.prototype // Object { } // null
이 코드는
Date객체를 생성한 다음 프로토타입 체인을 따라 이동하여 프로토타입을 기록합니다. 이것은myDate의 프로토타입은Date.prototype객체이고, 이 객체의 프로토타입이Object.prototype임을 알 수 있습니다.

실제로
myDate2.getMonth()와 같이 익숙한 메소드를 호출할 때, 당신은Date.prototype에 정의된 메소드를 호출하게 됩니다.
만약 객체의 프로토타입에 존재하는 속성을 정의하고자 한다면 어떻게 될까?
const myDate = new Date(1995, 11, 17); console.log(myDate.getYear()); // 95 myDate.getYear = function () { console.log("something else!"); }; myDate.getYear(); // 'something else!'
프로토타입 체인의 설명을 생각하면 그것은 예측 가능합니다. 우리가
getYear()을 호출할 때 브라우저는 해당 이름의 속성을myDate에서 찾습니다. 그리고 그것이 정의되지 않았을 때에만 prototype에서 찾습니다. 따라서 우리가getYear()을myDate에 따로 추가하게되면, 그 버전의myDate가 호출되는 것입니다.
이것을 속성의 "shadowing"이라 부릅니다.
Object.create()메소드는 새로운 객체를 생성하고 새 객체의 프로토타입으로 쓰일 객체를 지정할 수 있습니다.
예시:
const personPrototype = { greet() { console.log("hello!"); }, }; const carl = Object.create(personPrototype); carl.greet(); // hello!
greet()메소드를 가진 객체personPrototype을 생성하였습니다. 그리고Object.create()를 사용하여 새로운 객체carl의 프로토타입을personPrototype으로 지정하였습니다. 그리하여 이제 새 객체로greet()를 호출할 수 있으며, 프로토타입은 그것을 구현하게 도와줍니다.
자바스크립트에서는 모든 함수는
prototype이라는 속성을 가지고 있습니다. 함수를 생성자로 호출할 때, 이 속성은 새 객체의 프로토타입으로 설정됩니다.(관례적으로 속성의 이름은__proto__입니다.)
그리하여 생성자의
prototype을 설정한다면, 해당 생성자로 생성된 모든 객체는 그 프로토타입을 가질 수 있습니다.const personPrototype = { greet() { console.log(`hello, my name is ${this.name}!`); }, }; function Person(name) { this.name = name; } Object.assign(Person.prototype, personPrototype); // or // Person.prototype.greet = personPrototype.greet;
- 우선
greet()메소드를 가진personPrototype객체를 만들었습니다.- 만들 사람 이름을 초기화하는
Person()생성자 함수를 만들었습니다.personPrototype에서 정의된 메소드를Object.assign을 통해Person함수의prototype속성에 넣었습니다.- 이 이후에,
Person()생성자를 이용해 생성된 객체는Person.prototype을 프로토타입으로 가질것이고, 그것은greet메소드를 포함할 것입니다.사용 예시
const reuben = new Person("Reuben"); reuben.greet(); // hello, my name is Reuben!
이것은 또한
myDate의 프로토타입이 왜Date.prototype인지 설명됩니다. 이것은Date생성자의prototype속성이었던 것입니다.
위에서
Person생성자로 만든 객체들은 두 가지 속성들을 가지고 있습니다.
Person생성자가 직접 가지고 있던name속성- 프로토타입으로 설정된
greet()메소드
메소드는 프로토타입에 의해 정의되고, 데이터 속성은 생성자에 의해 정의되는 형태는 매우 보편적입니다. 왜냐하면 보통 메소드들은 우리가 만드는 객체에 똑같이 들어가 있지만 안의 데이터들은 각각 다른 값이 할당되기 때문입니다.
name과 같이 객체에 직접적으로 정의된 속성들을 스스로 정의한 프로퍼티(own properties)라고 합니다. 그리고Object.hasOwn()메소드를 통해 own property를 찾을 수 있습니다.const irma = new Person("Irma"); console.log(Object.hasOwn(irma, "name")); // true console.log(Object.hasOwn(irma, "greet")); // false
자바스크립트의 프로토타입은 매우 강력하고 유연하여, 코드를 재사용하고 결합할 수 있게 해줍니다.
특히 상속 버전을 지원하는데, 상속은 프로그래머가 시스템의 일부 객체가 다른 객체의 더 전문화된 버전이라는 생각을 할 수 있게 해주는 객체 지향 프로그래밍 언어의 특징입니다.
역시 사람은 영어를 해야하나 보다.. 번역하는게 가장 큰 장벽이었다.
프로토타입은 자바스크립트의 상속의 개념을 빛나게 해주는 속성같다. 이미 정의된 생성자의 프로토타입에 assign 매서드를 통해 프로토타입 속성(함수)을 추가할 수 있고, 이를 통해 생성된 인스턴스들이 그 속성(함수)에 접근할 수 있게 해준다. 또는 단순히 변수를 생성하고 거기에 프로토타입을 추가하여 특정 함수를 호출할 수 있게 해준다.
여러모로 편리한 기능같아 보인다. 더 좋은 점은 다른 강의를 들을 때 프로토타입이란 단어가 나와도 당황하지 않을 것에 다행이라 생각한다.