프로토타입과 프로토타입 체인
July 16, 2020
프로토타입
- 정의 : 프로토 타입 == 원형 객체의 원형을 말함
- 자바스크립트 내에서는 유일한 생성자는 객체이다. 함수 또한 객체이기 때문이다.
프로토 타입은 언제 생길까?
- 함수가 생성되면 함수의 Prototype이 같이 생성됨
-
Prototype 생기면서 proto 동시에 생김(프로토 타입의 부모)
function Foo(){}; let foo = new Foo(); foo - Foo() - Constructor() // 프로토타입 - __proto__ // 프로토 타입의 프로토타입 << 부모를 뜻함
프로토타입 체인은 무엇인가요?
- 현재 객체에서 해당 변수나 메서드가 없으면 프로토타입을 확인하고 프로토타입에도 없으면 프로토타입의 프로토타입을 찾아 올라간다(체인)
-
자바스크립트는 최상위 오브젝트는 Object이고 그 이후에는 null이기 때문에 종료조건은 proto === null 이면 종료를 하고 undefined를 리턴한다.
let f = function () { this.a = 1; this.b = 2; } let o = new f(); // {a: 1, b: 2} // f 함수의 prototype 속성 값들을 추가 하자. f.prototype.b = 3; f.prototype.c = 4; console.log(o.z) // undefiend // 1. f() 생성자의 프로퍼티 확인 // 2. 없다면 f().prototype 확인 // 3. 없다면 f().prototype.prototype 확인 // 4. 상위 프로토타입까지 찾고 null이면 undefined를 리턴한다.
클래스 문법은 프로토 타입과 다르게 상속으로 이루어져 있지 않나요?
- 결론을 말하자면 자바스크립트는 프로토타입으로 구현한 상속을 구현한 것이지 자바처럼 상속을 지원하지 않는다(단순한 문법설탕 같은거)
- 자바스크립트로 구현할 수 있는 상속은 총 3가지 위임형 상속, 연결형 상속, 함수형 상속이 있다.
-
위임형 상속 : 프로토타입에 함수를 정의하여 메모리를 절약할 수 있다. 단점은 프로토타입이 변경되면 모든 메소드가 변경되어 위험하다.
class Greeter { constructor (name) { this.name = name || 'John Doe'; } hello () { return `Hello, my name is ${ this.name }`; } } const george = new Greeter('George'); const msg = george.hello(); console.log(msg); // Hello, my name is George
-
연결형 상속 : 프로토타입을 인용하는게 아니라 protytype을 꺼내어 하나의 객체를 만드는 것이다.
const proto = { hello: function hello() { return `Hello, my name is ${ this.name }`; } }; const george = Object.assign({}, proto, {name: 'George'}); const msg = george.hello(); console.log(msg); // Hello, my name is George
-
함수형 상속 : 기존 객체를 확장 시키며, 클로져를 통해 구현
const rawMixin = function () { const attrs = {}; return Object.assign(this, { set (name, value) { attrs[name] = value; this.emit('change', { prop: name, value: value }); }, get (name) { return attrs[name]; } }, Events.prototype); }; const mixinModel = (target) => rawMixin.call(target); const george = { name: 'george' }; const model = mixinModel(george); model.on('change', data => console.log(data)); model.set('name', 'Sam'); /* { prop: 'name', value: 'Sam' } */
static 문법은 무엇인가요?
-
인스턴스 없이 호출이 가능한 함수 주로 유틸함수에 많이 사용된다.
class Hello{ static foo(){ console.log('hello static') } } Hello.foo() // hello static let bar = new Hello(); bar.foo() // uncatch typeErrors