JS ) 자바스크립트의 객체지향

devHyuck·2023년 11월 15일

Java Script

목록 보기
3/4
post-thumbnail

Javascript 탄생비화
Javascript를 창시한 Brendan Eich는 언어를 개발할 당시 유행하던 객체지향에 한계를 느끼고 LISP, scheme 등 함수형 프로그래밍에 관심을 가지고 있었기에 함수형 프로그래밍 형태로 언어를 만들고 싶어 했습니다. 하지만 Netscape의 그의 상사는 당시 개발자들이 제일 많이 쓰던 Java와 같은 문법으로 만들기 요구했기 때문에 결국 둘의 혼종의 형태로 세상에 나오게 되었습니다.
참조 : (요즘IT) 자바스크립트에서 객체지향을 하는 게 맞나요? / 테오의 프론트엔드

자바스크립트에는 객체지향 문법이 있습니다.
하지만 다른 객체지향 프로그래밍 언어와는 좀 다른 모습이라고 하는데요.
저는 다른 언어를 아직 배워보지 않아 정확한 차이점을 알지는 못 합니다...😅

이제 자바스크립트의 객체지향문법에 대해 알아보자하는데 객체지향 프로그래밍이란 무엇일까요?

객체지향 프로그래밍 간단정리

우리가 자주 사용하는 오브젝트가 객체입니다.
자바스크립트에서 객체는 보통 이런 모습이죠.

const 객체 = {
	name : '객체',
	type : 'Object',
	tool : function () {
		console.log('Im object!');
}

하나의 변수안에 많은 데이터가 모여있는 모습인데요.

객체는 데이터를 묶어서 편하게 관리하기 위해서 탄생했다고 합니다.
프로그래밍을 하다보면 비슷한 형태의 데이터를 수정하고 변경하는데 데이터가 전부 나뉘어져 있으면 관리하기가 어려워요.
그래서 이렇게 데이터를 모아 필요할때 꺼내서 수정, 변경하여 사용하기 위해서 객체를 만들었습니다.

그럼 자바스크립트에서 객체를 어떻게 다루는지 살펴봅시다.

Constructor

function Human (name, age) {
	this.name = name;
	this.age = age;
	this.sayHi = function () {
		console.log(`Hi my name is ${this.name}`)
	}
}

const human1 = new Human('Kim', '26');
const human2 = new Human('Jason', '34');

컨스트럭터비슷한 형태의 객체를 복사하고 싶을때 사용합니다.
쉽게 말하면 객체복사기죠.
human1은 Kim이라는 name과 26이라는 age를 가진 객체가 되고 human2는 Jason이라는 name과 34라는 age를 가진 객체가 됩니다.
컨스트럭터로 만든 객체는 인스턴스(Instance)라고 불러요.
컨스트럭터를 이용해 객체를 만들고 싶을때는 new 키워드를 사용해서 만듭니다.

Prototype

인스턴스가 만들어질때 컨스트럭터가 가진 속성들을 그대로 가져오는 걸 객체지향 용어로 상속(Inheritance)이라고 합니다.
HTML처럼 상위 객체를 부모, 하위 객체를 자식이라고 하기도 하죠.
상속을 할 때는 프로토타입(Prototype)도 물려주는데 프로토타입을 쉽게 비유하자면 유전자라고 생각하시면 됩니다.

function Human (name, age) {
	this.name = name;
	this.age = age;
	this.sayHi = function () {
		console.log(`Hi my name is ${this.name}`)
	}
}

console.log(Human.prototype);
// 뭔가 출력된다

컨스트럭터에는 프로토타입이 자동으로 생성됩니다.
여기에 있는 데이터는 자식들이 그대로 물려받아서 사용할 수 있어요.

function Human (name, age) {
	this.name = name;
	this.age = age;
	this.sayHi = function () {
		console.log(`Hi my name is ${this.name}`)
	}
}

Human.prototype.gender = 'male';
const human1 = new Human('Kim', '26');
const human2 = new Human('Jason', '34');

console.log(human1.gender);
// male

우리가 human1.gender를 출력할때 자바스크립트는 정해진 순서에 따라 확인합니다.
첫번째로 human1gender값이 있는지 확인.
두번째로 human1의 부모 프로토타입에 gender값이 있는지 확인.
자바스크립트는 gender라는 값을 찾을때까지 반복합니다.

우리가 배열과 객체를 만들면 내장함수를 사용할 수 있는데요.
모두 프로토타입이 있기에 사용하는 것입니다.

const arr = [1, 2, 3];
console.log(arr.toString());

배열에 toString()이라는 함수를 사용했을때 arr에 해당함수가 있는지 확인하고 없다면 부모의 prototype을 확인하고 계속 반복합니다.

분명 arr은 컨스트럭터를 이용해서 만든게 아니라 그냥 변수에 배열을 넣은건데 왜 부모가 있는지 의아하죠.

그런데 사실 우리가 배열과 객체를 만들땐 컨스트럭터를 이용해서 만든 것과 동일한 방식으로 만들어집니다.

const arr = [1, 2, 3]; // 우리가 적는 방식
const arr = new Array(1,2,3); // 내부적으로 배열을 만드는 방식

자바스크립트에는 Array라는 배열을 만들어주는 컨스트럭터가 있습니다.
객체도 똑같이 new Object()를 사용하여 만들어져서 부모의 prototype에 있는 함수들을 우리가 사용할 수 있습니다.

Class

위에서 본 함수를 이용해서 컨스트럭터를 만드는 방식은 예전 방식입니다.
ES6 버전부터는 class 키워드를 사용해서 컨스트럭터를 만들 수 있습니다.

class 부모 {
	constructor(name) {
		this.name = name;
	}
	// prototype에 입력되는 내장함수
	sayHello() { console.log('hello') }
}

var 자식 = new 부모('kim');

자식.sayHello() // hello

function으로 만든 것과 큰 차이는 없습니다.
constructor안에 상속할 데이터를 넣고 prototype에 추가하고 싶은 데이터는 constructor밖에 입력하면 됩니다.

또 class를 상속받는 class를 만드는 방법이 있는데 extends 키워드 입니다.

class 할아버지 {
	constructor(name) {
		this.= 'Kim';
		this.이름 = name;
	}
	sayHi() {
		console.log('안녕 저는 할아버지에요');
	}
}

class 아버지 extends 할아버지 {
	constructor(name) {
		super(name);
		this.나이 = 50;
	}
	sayHi() {
		console.log('안녕 저는 아버지에요');
		// 부모 class의 prototype을 의미
		super.sayHi();
	}
}

똑같이 class로 생성하고 상속받고 싶은 class를 extends 키워드 뒤에 적어주면 됩니다.

클래스를 복사한다고 생각하면 되는데 주의점이 있습니다.
extends를 사용해서 만든 class는 this를 마음대로 쓸 수 없어요.

super()를 적고나서 this를 사용 할 수 있는데 superconstructor{}안에서는 물려받는 class의 constructor의 역할을 합니다.
그래서 super()안에 파라미터도 옮겨줘야 정상적으로 작동이 됩니다.

또 prototype 공간에서의 super()부모의 prototype을 의미하는데요.
아버지의 sayHi()함수에 할아버지의 유전자에 담긴 함수를 넣고 싶다면 super.함수이름()을 입력하면 부모의 prototype에 담긴 함수를 사용 할 수 있습니다.

class에서 사용하는 키워드는 또 있는데 바로 getset입니다.

class Human {
	constructor(name, age) {
		this.name = name;
		this.age = age;	
	}
	get nextAge() {
		return this.age + 1;
	}
	set setAge(age) {
		this.age = parseInt(age);
	}
}

컨스트럭터의 함수에서 사용되는 키워드인데 각각 getter 함수, setter 함수라고 부릅니다.
이 함수들에는 제약이 있는데 getter 함수는 값을 가져오는 함수이기에 꼭 return이 존재해야 합니다.
setter 함수는 데이터를 수정하는 함수이기에 파라미터가 꼭 하나가 존재해야합니다.

이렇게 함수를 이용해서 내부의 데이터를 다루는 것에는 많은 이점이 있는데요.

데이터를 직접 꺼내서 수정하기보다 함수를 이용해서 수정하면 검사와 필터링을 미리 할 수 있어서 오류예방을 하고 데이터 처리 방법을 정의할 수 있어 관리가 용이해집니다.

setAge함수에서 age는 숫자데이터가 들어가야 합니다.
만약 실수로 문자를 입력해도 함수내부에 parseInt라는 안전장치를 사용해서 항상 숫자데이터가 입력되게 했습니다.

마무리

자바스크립트는 객체지향 프로그래밍언어로 탄생하지 않았지만 객체를 다룰 수 있는 많은 문법이 있습니다.
자바스크립트는 알면 알수록 오묘하고 매력적인 언어같네요. 🙂

profile
프론트엔드 개발자

0개의 댓글