[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 |
댓글