본문 바로가기

기술들/javascript

[Today I Learned] 10월 28일(수) - 객체지향언어

- 오늘 공부했던 부분.

 #객체지향 

 

 😄javascript는 왜(why) 객체지향 언어(OOP)일까에 대한 생각? 

javascript를 배우면서 처음 객체(object)를 마주했을 때 들었던 생각은 배열(Array)보다는 조금 더 명확하게(key를 이용) 데이터를 관리할 수 있고, 뭔가 익숙해지기가 배열보다는 훨씬 어려울 것 같다는 것이 객체를 마주한 나의 첫 느낌이었다. 그래서 이 당시 난 이 객체가 중요하지 않은 개념이었으면 하는 바람이 있었다. 그렇지만 지금의 나는 javascript가 대표적인 객체지향 언어(OOP)라는 것을 알고 있다.

 

나는 'javascript는 객체지향언어다'임을 확실히 인지하게 된 계기는

1. 객체에 value값으로 익명함수(function)를 넣을 수 있다는 점을 알게 된 후부터.

2. (1)을 인지하고 Math.prototype.push에서 dot의 역할! 을 알게 되고 나서였다.

객체에 특정 property(key)에 속해 있는 value에 접근하기 위해선 dot notaion과 bracket notaion 두 가지 방법이 있는데 주로 dot notation으로 접근한다. 만약 Car라는 이름을 가진 객체에 value값으로 어떤 기능을 구현하는 익명 함수가 들어있다고 하자. 그럼 이 value(함수)의 property(obj의 key)의 이름은 함수가 어떤 기능을 하는지에 따라 마음대로 설정해줄 수 있다. (아래 예시)

let Car = {
  position : 0,
  move : function() {         //move라는 메소드! value값으로 익명함수가 들어옴, 익명함수의 기능에 맞게
           this.position++;     // move(차가 움직인다)라는 이름을 Car객체의 key값으로 정해줌. 
           return this.position;
         }
}
//위 예시에서 move라는 메소드를 사용하기 위해선 Car.move()를 해주면 된다. (그럼 position이 1씩 늘어난다) 

 

늘 나는 javascript코드에서 많이 보이는 dot(.)이 어떤 역할을 하는지 궁금했었는데 위 사실을 배운 후부터 dot의 역할은 객체의 프로퍼티의 값에 접근하기 위한 방식임을 알게 되었다(그 값은 number나 string같은 원시 타입이 될 수도 있고 function이나 object와 같은 참조 타입이 될 수 있음).

 

그리고 이 dot notation방식은 javascript로 만들어진 어떤 프로그램의 코드를 보면 정말 많이 보이는 방식임을 알 수 있다. 그렇다는건 결국 javascript는 수많은 객체(Object)에 많은 정보(변수, 메서드)를 저장해 놓고 그 객체를 통해 정보(변수, 메서드)를 사용하는 언어라는 점을 말한다. 그래서 나는 javascript가 객체(object)를 위주로 사용되어지는 '객체지향 언어'임을 알게 되었다.  

 

 

 😄javaScript에서 Object를 생성하는 여러 가지 방법들 

다음 4가지가 있다. 

1. Functional 방식

2. Functional Shared 방식

3. Prototypal 방식 (Object.create 이용)

4. Pseudoclassical 방식(익혀야 할 방식!)

 

간단히 살펴보면

1) Functional 방식은

말 그대로 함수안에 Object가 들어있는 방식이다. 

let refrigerator = function () {
	let obj = {};  				 	//객체생성
    	obj.temperature = 0;  				//기능구현
    	obj.freezing = function() {		 	//기능구현
    			return this.temperature--;
    	}
  	return obj; //만들어준 객체리턴, 리턴함으로써 refrigerator는 obj자체가 된다.
    }
    //사용시 : refrigerator.freezing()  
                   

함수 안에 실제기능을 하는 obj를 만들어 주고 이 obj를 리턴해서 바깥함수의 이름인 refrigerator로 사용할 수 있게 한다. 

 

2) Functional shared 방식은 

Functional 방식에서 함수 안에 구현된 메서드(함수 내부에 있는 함수)를 외부로 빼주고,

다시 함수 내부로 합쳐주는 방식이다. 

var extend = function(to, from) { //refrigerator 내부 obj객체와 외부 methods객체를 합쳐주는 기능
  for(var key in from) {
    to[key] = from[key];
  }
};

let methods = {}   //외부 객체를 만들고
methods.freezing = function() {		//refrigerator함수 내에서 구현했던 freezing을 이 객체에 넣는다.
   	return this.temperature--;
}
	


let refrigerator = function () {
    let obj = {};  		//객체생성
    obj.temperature = 0;  	//기능구현
    extend(obj, methods);       //이로써 obj에 methods 객체의 기능이 들어감.
  	return obj; //만들어준 객체리턴, 리턴함으로써 refrigerator는 obj자체가 된다.
    }
    //사용시 : refrigerator.freezing()  

왜 이렇게 헷갈리게 왔다갔다 하냐? 😡(메모리 효율땜시!)

Functional 방식은 새로운 instance를 생성할 때마다 함수 안에서 구현한 메서드들이 그에 맞게 생성되기 때문에 메모리를 Functional shared 방식보다 많이 차지하게 된다.

Functional shared 방식은 인스턴스를 계속 생성해도 그때마다 밖으로 빼준 메서드를 호출만 해서 불러오기 때문에 메서드가 차지하는 메모리가 Functional방식보다 현저하게 줄어든다.  

 

3) Prototypal 방식 (Object.create 이용)

좀 간단하다. refrigerator 함수 내에 생성한 obj를 아예 밖으로 빼주고 refrigerator함수 내부에서 Object.create(obj)를 통해 객체를 새로 복사해서 사용한다. 

let obj = {}   //외부 객체를 만들고
obj.temperature = 0;		//기능구현
obj.freezing = function() {	//기능구현	
   	return this.temperature--;
}

let refrigerator = function () {
    let newObj = Object.creates(obj);    //외부에서 선언한 객체를 가져옴. 
  	return newObj; 			//만들어준 객체리턴, 리턴함으로써 refrigerator는 obj자체가 된다.
    }
    //사용시 : refrigerator.freezing()  

4) Pseudoclassical 방식 (발음 : 수도클래지컬)

내가 자주 사용해야 될 방식이다. prtotype으로 메서드를 구현하고 new방식으로 instance를 생성해서 객체를 사용하면 된다. 말은 어려운데 보면 간단하다. 

let refrigerator = function () { //함수생성 => new를 통해 곧 객체역할을 할 함수임.
	this.temperature = 0;  //여기서 this는 new로 instance를 생성했을 때 만들어지는 객체를 의미. 당근 temperature는 객체의 key이고 할당된 0은 value!
}

refrigerator.prototype.freezing = function () { //메소드를 property를 통해 설정!
	return `${this.temperature--}'C`;  
}

let 냉장고1 = new refrigerator(); //냉장고1 이라는 instance를 생성! 이때 냉장고1(객체)안에는 위에서 구현한 temperature와 메소드freezing이 프로퍼티로 존재!

냉장고1.freezing() // -1'C

자바스크립트는 다른 객체지향언어와는 달리 Class를 쓰지 않는다. 그 대신 prototype이라는 것을 이용해서 만들고자 하는 객체를 구성할 수 있다. 그래서 자바스크립트는 prototype을 기반으로 하는 객체지향언어라고 할 수 있다.

 

사실 위 4)Pseudoclassical방식은  요새 잘 쓰지 않는데, 그 이유는 상속을 하는데 그 과정이 복잡하기도 하고 최근 이를 대체할 수 있는 Class 문법을 도입했기 때문이다. Class를 사용하면 상속은 껌이다. 

이에 대한 것은 다음글에서 자세히 설명하겠다.

'기술들 > javascript' 카테고리의 다른 글

객체지향언어 - prototype과 __proto__의 관계  (0) 2020.10.31
Twittler과제(2) - CSS  (0) 2020.09.07
Twittler과제(1) - HTML부분  (0) 2020.08.28
[공부했던 것 정리] Scope(2)  (0) 2020.08.18
[공부했던 것 정리] Scope(1)  (0) 2020.08.11