코드에 정답은 없다고 하지만 중복되는 코드만큼은 효율성, 메모리 ..등 여러가지 면에서 피하는 게 좋다.
중복을 줄이고 해당 코드를 재사용하는 대표적인 방안으로 생성자 프로토타입(prototype)상속과 믹스 인 (Mix in) 함수가 있다.
용어가 뒤섞여 사용될 것 같아서 켄님의 수업 내용을 기반으로 정리하자면
생성자 constructor= 인스턴스의 아빠이자 프로토타입의 남편
프로토타입 prototype = 인스턴스의 엄마이자 생성자의 아내
메소드 method= 능력
인스턴스 instance= 자식으로 칭하겠다.
프로토타입prototype
상속은 별다른 조치 없이도 자식instance
이 생성될 때부터 사용 가능한 선천적 능력이다. 자식은 곧바로 엄마의 능력prototype.method
을 사용할 수 있기 때문이다.
이처럼 생성자 함수의 ptototype에
재사용을 원하는 능력method
를 만들고 나면 이후 해당 생성자의 ‘모든’ 자식instance
들은 엄마의 능력prototype.method
을 사용할 수 있게 된다.
즉, instance
가 직접 메소드를 가지고 있지 않아도 메소드를 사용할 수 있다는 것이다.
instance.__proto__
는 아빠의 아내 Constructor.prototype
이다.자식instance
들은__proto__
를 통해 엄마prototype
와 ‘연결’ 되어있기 때문이다. 이처럼 같은 생성자 아래의 자식들은 모두 같은 프로토타입과 연결되어 있다.
new 키워드로 생성된 모오든 instance들은 proto를 통해 본인 생성자의 프로토타입에 접근할 수 있으므로 중복해서 만들거나, 각각의 객체들이 직접적으로 가지고 있지 않아도 프로토타입의 코드를 재활용하여 메소드를 사용할 수 있는 것이다.
컴퓨터 용어로 쓰이는 ‘상속’은 일반적인 의미와 조금 다르다. 예를 들어 재산 상속의 경우 상속 해주는 자의 소유물이 상속 받는 자의 소유물로 넘어간다.
하지만 객체 메소드 상속의 경우 자식이 능력 method
을 상속받는다고해서 부모의 능력method
이 사라지지지 않으며 나아가 자식에게 능력 method
가 생성되는 것도 아니다. 단지 같은 생성자 하의 모든 자식이 엄마의 능력 prototype.method
을 마치 내 것처럼 마음대로 쓸 수 있게 된 것 뿐이다.
prototype
상속이 생성자의 인스턴스들이 마치 특권처럼 가지는 선천적 능력이라고 한다면 Mix in은 객체가 이미 생성된 후 능력method
을 추가하는 것이다.
prototype
으로 같은 메소드를 사용하기 위해서는 생성자의 프로토타입으로 메소드가 만들어져있고 instance
가 이를 상속 받아 사용했다.
그런데 만약 객체들이 같은 생성자의 자식instance
들이 아니거나 literal로 만들어진 객체들을 단지 메소드 공유만을 위해 생성자-프로토타입으로 바꾸는 것이 현실적으로 힘들다면 중복 코드를 써야만 하는 걸까?
디자인 패턴의 핵심은 근본적인 원리를 파악한다면 비슷한 기능을 하는 또다른 도구를 만들 수 있다는 것에 있다.
예를 들어 위의 Bird , Cat 두 생성자 함수는 아무런 프로토타입 메소드가 없는 상태이다. 만약 이들의 모든 자식 instance 들에 hunt 라는 같은 능력method
를 추가하고 싶다면
Bird.prototype.hunt = function () {};
Cat.prototype.hunt = function () {};
이렇게 프로토타입 메소드를 사용하여 자식들이 엄마의 능력을 마음껏 사용하게 만들면 된다.
하지만 모든 자식들이 아닌 특정 몇몇instance
에만 hunt라는 메소드를 추가하고 싶다면 ???
이러한 경우에 프로토타입을 사용하지 않아도 같은 메소드를 사용할 수 있게 구현하는 것을 Mix In 함수라고 부른다.
위의 예제처럼 Mixin 함수를 만들어 사용할 수 있다.
Mixin 함수는 객체에 메소드를 추가하기 때문에 객체가 인자로 들어온다.
그리고 원하는 메소드를 작성하면
(위의 경우엔 target.hunt = function () {};
)
이후 함수가 호출 되었을 때 인자로 들어온 객체method
에 능력을 추가 해준다.
즉, 객체가 이미 생성된 후에 필요한 능력들을 후천적으로 만들어 주는 것이다.
따라서 이 경우는 프로토타입 상속처럼 빌려 사용하는 것이 아니고 해당 객체에 메소드가 ‘생성’된다.
굉장히 간단하면서도 대단하다..
나아가 생성자의 프로토타입에 Mix In 함수를 사용한다면 이후 해당 생성자들의 모든 자식 instance
들에 같은 메소드들이 생성된다.
Mixin(Bird.prototype);
Mixin(Person.prototype);
즉, 여러 생성자에 같은 메소드를 사용하고 싶을 때에도 mix in함수를 만들어 사용하면 된다.
프로토타입 상속은 객체가 생성시부터 생성자의 프로토타입에 접근할 수 있다는 선천적 능력을 이용하여 중복을 줄인 것이고, 믹스 인은 객체가 생성된 후에 같은 메소드를 사용할 수 있게 또다른 함수를 만들어 추가해줌으로써 중복을 줄인 것이다.
상황에 따라 필요에 따라 적절하게 프로토타입과 믹스인을 사용할 수 있다.