[Chapter 5] 상속
- 상속의 유용한 점은 코드를 재사용 하는 것이다.
새로만든 클래스가 기존 클래스와 매우 유사하다면 상속을 통해 다른 부분만 구현해낼수 있다
- 자바스크립트는 클래스를 기반으로 하는 상속을 지원하지 않고
프로토타입 체인을 이용하여 상속을 구현해낸다. (객체가 다른 객체로 바로 상속 된다) 이러한 상속의 구현방식으로 여러가지 패턴이 있다.
01] 의사 클래스 방식(Pseudoclassical)
- 의사 클래스는 클래스처럼 행동하지만 진짜 클래스는 아니다.
- 클래스가 없는 자바스크립트가 클래스 기반의 상속 방식을 흉내내는 것.
- 생성자 함수를 통해서 객체를 생성해야 한다.
//동물 생성자 함수 정의
var Animal = function( name ){
this.name = name;
}
//동물의 이름 속성 추가
Animal.prototype.get_name = function(){
return this.name;
};
//console.dir(Animal);
//myAnimal을 Animal의 새 인스턴스로 대체
var myAnimal = new Animal( 'morrie' ); // <-- 객체를 생성하기 위해 만들어지는 또 다른 객체
console.log( '내 애완동물 이름은 ' + myAnimal.get_name() + '입니당' );
//의사 클래스
var Cat = function( name ){
this.name = name;
this.saying = 'meow';
}
//Cat 프로토타입을 Animal의 새 인스턴스로 대체
Cat.prototype = new Animal('test cat');
console.dir(Cat);
var morrie = new Cat( 'morrie' );
console.log( morrie.name + '의 소리 : ' + morrie.saying ); // morrie 의 소리 : meow 출력
- 의사 클래스는 자바스크립트에 익숙하지 않은 프로그래머들에게 편안함을 제공하지만 자바스크립트의 장점을 가리게 되는 법이다.
- 위 예제의 문제점으로 모든 객체의 속성이 public 이라는 것과,
생성자 함수 new 연산자로 실행하지 않으면 this 바인딩에 의해 this는 새로운 객체에 바인딩 되지 않고 전역객체(window)에 연결된다는 문제가 있다.
02] 객체를 기술하는 객체(Object Specifiers)
- 생성자가 매우 많은 매개변수를 갖게되는 경우 생성자가 인수를 받는 대신에 객체를 기술하는 하나의 객체를 받도록 정의 할 수 있다.
var test = testFunc( n, c, i, s );
위 코드 아래와 같이 작성 할 수 있다.
var test = testFunc({
name : n,
color : c,
idx : i,
state : s
});- 인수는 꼭 순서를 맞출 필요가 없으며, 생성자가 기본값 설정을 잘 하고 있다면 인수를 생략 할 수도 있다
03] 프로토타입 방식
- 프로토타입에 기반한 패턴에서는 클래스가 필요 없다.
- 프로토타입에 의한 상속은 클래스에 의한 속성보다 더 간단하다.
//객체 리터럴로 동물객체 생성
var animal = {
name : '',
says : function(){
return this.saying;
}
};
//Object.create 메소드로 인스턴스를 만들 수 있다.
//create() : 넘겨받은 객체를 프로토타입으로 하는 새로운 객체를 생성하는 메소드
var my_cat = Object.create(animal);
var my_dog = Object.create(animal);
console.dir(my_cat);
console.dir(my_dog);
//상속받아온 인스턴스에 원하는 속성이나 메소드 추가
my_cat.name = 'morrie';
my_cat.saying = 'meow';
my_dog.name = 'dogidogi';
my_dog.saying = 'bow wow';
console.dir(my_cat);
console.dir(my_dog);
04] 함수를 사용한 방식
- 프로토타입에 의한 상속 패턴의 한가지 단점은 private 속성을 가질수 없다는 것이다. (private 변수, private 메소드도 모두 생성할 수 없다.)
- 함수형 패턴은 유연성이 매우 좋다. 이 패턴은 의사 클래스 패턴보다 작업량이 적고 캡슐화와 정보은닉에 사용 할 수 있다.
//객체 생성
var animal = function( spec ){
var that = {}; //필요한 private 변수
// 새로운 객체를 할당하고 메소드를 추가.
that.get_name = function(){
return spec.name; // <-- private 속성이다
};
that.says = function(){
return spec.saying; // <-- private 속성이다
}
// 새로운 객체 반환
return that;
};
var myAnimal = animal( {name : 'morrie'} );
console.log( myAnimal.get_name() );
05] 클래스 구성을 위한 부속품
- 제품을 만들 때 부속품을 가져다 조립을 하듯이 객체를 구성할 때도 같은 방법으로 할 수 있다
var eventtuality = function ( that ) {
var registry = { };
that.fire = function (event) {
var array, func, handler, i, type = typeof event === 'string' ? event : event.type;
// 해당 이벤트에 상응하는 처리 함수 목록 배열이 있으면
// 루프를 돌면서 이 배열에 등록돼 있는 모든 처리 함수를 실행 시킨다.
if ( registry.hasOwnProperty(type)){
array = registry[type];
for ( i = 0 ; i < array.length; i += 1){
handler = array[i];
func = handler.method;
// 처리 함수 배열에 속하는 항목 하나는 처리 함수인 method 와 매개변수인
// parameters 라는 배열로 구성됨, method 가 함수 자체가 아니라 이름이면,
// this 에서 해당 함수를 찾음.
if ( typeof func === 'string' ) {
func = this[func];
}
// 처리 함수 호출, parameters 가 있으면 이를 넘김. 없다면 event 객체를 넘김
func.apply( this, handler.parameters || [event] );
}
}
return this;
};
that.on = function (type, method, parameters) {
// 이벤트 등록 handler 항목을 만들고 해당 이벤트 타입의 배열에 추가
// 만약 기존에 배열이 없다면 해당 이벤트 타입에 대해 새로운 배열 생성
var handler = {
method : method,
parameters : parameters
};
if ( registry.hasOwnProperty ( type ) ) {
registry[type].push(handler);
} else {
registry[type] = [handler];
}
return this;
};
return that;
};
var oDiv = eventtuality(document.getElementById('divTest'));
oDiv.on('click', function (){
console.log('test')
});
var oButton = eventtuality(document.getElementById('button_test'));
oButton.on('click', function(){
console.log('test_button');
});
//HTML <div id="divTest" onclick="this.fire(event)"></div> <button id="button_test" onclick="this.fire(event)">test</button>
//CSS
#divTest{
width: 100px;
height: 100px;
border: 1px solid #ddd;
cursor:pointer;
}
'Web > Javascript' 카테고리의 다른 글
| 정규표현식 (0) | 2018.02.28 |
|---|---|
| 배열 (0) | 2018.02.28 |
| 콜백, 모듈, 커링, 메모이제이션 (0) | 2018.02.27 |
| 함수 - (스코프, 클로저) (0) | 2018.02.26 |
| 함수 (0) | 2018.02.26 |
댓글