javascript 객체지향프로그래밍 02 - 모듈화, 프로토타입

|

javascript 객체지향프로그래밍02 - 모듈화, 프로토타입

윤지수님의 웹 프론트엔드 강의
프로토타입 기반의 객체지향적인 설계방법에 대해서 알아본다

프로토타입 기반의 객체지향적인 설계방법

  • 프로토타입 기반의 객체지향적인 설계방법은 자바스크립트의 일반적인 패턴으로 보기 어려울 수 있으나, 알게되면 자주 쓰게되는 패턴이다.
  • 예를 들어 아래와 같이 객체가 필요할 때마다 매번 객체를 만드는 일은 번거로운 일이다.
var oName = {
	name : 'jisu',
	getName : function(){
		return this.name;
	}
}

var oName2 = {
	name : 'siwa',
	getName : function(){
		return this.name;
	}
}
  • 그럼 객체를 반환하는 함수를 만들 수도 있다.
function Name(_name){
    var oName = {
        name : _name,
        getName : function(){
            return this.name;
        }
    }

    return oName;
}

Name('siwa'); // Object{name: 'siwa', getName:function()} 리턴
var o = Name('siwa');
o.getName(); // 'siwa' 리턴

객체 생성자 함수와 new 키워드

  • 위와 같은 방법 말고 객체를 생성해주는 표준적인 방법이 존재한다.
 function Name(_name){
		console.log('this is',this);
		this.name = _name;
		this. getName = function(){
        return this.name;
    }
}

// 함수를 그냥 호출했을때
Name('monkey'); // this is window, undefined 리턴

// new 키워드와 함께 함수를 호출했을 때
new Name('monkey'); // this is Name{}, Name{name:'monkey', getName()} 리턴
var o = new Name('monkey');
o.getName(); // 'monkey'
  • new라는 키워드와 함께 함수를 호출하면,
    그 함수는 this에 새로운 오브젝트를 만들어서 this 안에 속성들을 담은 상태로 반환한다.
    (new 키워드와 함께 불려지는 함수는 생성자 함수이고 생성자 함수는 대문자로 시작한다.)
// new 키워드를 붙여서 함수를 호출했을때 함수 내부에서 발생하는 일
function Name(name){
	(var this = {};) // => 함수 앞에 new를 붙였을때 내부적으로 추가되는 코드
	this.name = name;
	this.getName = function(){
		return this.name;
	}
	(return this;) // => 함수 앞에 new를 붙였을때 내부적으로 추가되는 코드
}

new Name('siwa'); // {오브젝트} 리턴
  • 이는 객체지향적인 언어를 표방하는 기능, 클래스를 만드는 것과 비슷하다.
    (new라는 키워드는 자바에서 클래스를 호출해서 인스턴스를 만드는 것과 비슷하다)

객체 생성자 함수의 활용 - 모듈화

  • 기능별로 모듈화 시킨 독립적인 클래스 단위로 그루핑할때 생성자 함수를 활용할 수 있다.
  • 예를 들어 구글지도 UI를 만들 때, 화면에 보이는 기능 단위 즉 의미적으로 다른 기능이라면 (ex. 사진, 공유, 검색, 지도화면, 설정) 각각의 기능을 별도 모듈(클래스 단위)로 만들 수 있다.
  • 모듈화 패키징 설계 예시
// 모듈화 수도코드 예시
// 지도를 표현하는 영역 클래스
function Map(){}
// 지도를 검색하는 영역 클래스
function SearchMenu(){}
// 사진을 슬라이드 하는 영역 클래스
function ViewCurrentPhotos(){}

var oMap = new Map({});
oMap.setDraw();
var oSearchMenu = new SearchMenu({width: '200px'});
// 여러가지를 인자로 줘서 인스턴스를 만들고 (oMap, oSearchMenu)
oSearchMenu.clearText();
oSearchMenu.autocomplete();

객체 생성자 함수의 활용 - 프로토타입

function Map(){
	this.drawMap = function(){}
}

// 인스턴스 생성
var oMap = new Map();
var oMap2 = new Map();
var oMap3 = new Map();
// 상기의 3개 인스턴스는 각각의 메모리 공간에 동일한 오브젝트를 갖고 있다. => 비효율적
// 이를 해결하기 위해 프로토타입을 활용할 수 있다. => this.drawMap과 메모리공간을 공유
  • 모든 함수에는 프로토타입이라는 오브젝트가 존재한다.
  • 생성자에 프로토타입을 연결하여 생성자 함수를 통해서 만들어진 함수들이 프로토타입의 함수를 공유할 수 있다.
  • 모든 브라우저에서 지원한다.
prototype의 동작방식
  • 프로토타입 예시
// 프로토타입 예시
function Map(_name){
	this.name = _name; // 인스턴스마다 다르게 가져야 할 속성
}

Map.prototype.setDraw = function(){
	console.log('drawing!');
}

// 인스턴스 생성
var oMap = new Map();
debugger // debugger를 걸어서 개발자도구에서 디버깅 가능
var oMap2 = new Map();
var oMap3 = new Map();

oMap.setDraw(); // drawing!
oMap.__proto__.setDraw(); // drawing! => 내부에서 쓰는거라 이렇게 쓰면 안됨
인스턴스(oMap)이 생성자함수의 prototype 객체의 속성을 상속받은 모습