프로토타입
- 정의 : 프로토 타입 == 원형 객체의 원형을 말함
- 자바스크립트 내에서는 유일한 생성자는 객체이다. 함수 또한 객체이기 때문이다.
프로토 타입은 언제 생길까?
-
함수가 생성되면 함수의 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