(JS) OOP / 객체 지향 프로그래밍 (1/2)

호두파파·2021년 3월 22일
0

JavaScript

목록 보기
22/25


OOP : Object Oriented Programming (객체 지향 프로그래밍)

  • 객체 지향 프로그래밍은 동작하는 부분을 캡슐화해서 이해할 수 있게한다.
  • 함수형 프로그래밍은 동작하는 부분을 최소화해서 코드 이해를 돕는다.

객체지향의 경우 객체 안에 상태를 저장한다. 각 객체는 메시지를 받을 수도 있고, 데이터를 처리할 수도 있으며, 또 다른 객체에게 메시지를 전달할 수도 있다.

객체지향 프로그래밍은 보다 유연하고 유지보수하기 쉬우며 확장성 측면에서도 유리한 프로그래밍을 하도록 의도되었다.

생성자(constructor)함수와 인스턴스 생성

생성자(constructor) 함수

자바스크립트는 생성자(constructor) 함수와 new 연산자를 통해 인스턴스를 생성하면 생성자(constructor) 함수라고 한다. 좀 더 직관적으로 생성자(constructor)함수를 정의하면 객체를 생성하는 함수가 생성자(constructor)함수이다.

생성자(constructor) 함수는 클래스이자 생성자의 역할을 한다.
다른 언어에서는 class가 있지만 자바스크립트에서는 class가 없다. 대신 생성자 함수가 그역할을 한다.

function foo() {} // 생성자(constructor)함수
new foo // 인스턴스 
var obj = {}; // 생성자(constructor) 함수는 Object
var obj = new Object(); 
var arr = [];
var arr = new Array(); // 생성자(constructor) 함수는 Array

생성자(constructor) 함수는 일반함수와 구분해 작성한다.

function Person (name) {
  this.name = name;
  this.gender = gender;
  this.sayHello = function() {
    alert(this.name + ' said hello');
  }
  this... // 사람의 속성과 메소드를 더 정의할 수 있다.
}
new Person;
// 첫 글자는 대문자로 표기해준다.
// this를 사용한다. 

함수를 만들때처럼 function을 쓰지만, 함수와는 달리 대문자로 시작하게 된다. 이것이 규칙이다. 생성자를 바탕으로 실제 사람 객체를 만들 수 있다. 생성자함수를 호출할때는 new 생성자(인자)로 호출할 수 있다.

인스턴스 생성

생성자 함수와 ptorotype 기능을 모두 빌려쓸 수 있는 객체이다.

function Person(name) {
  this.name = name;
}
var person1 = new Person(hodoo); //인스턴스
var person2 = new Person(wero); // 인스턴스
 
//person1과 person2는 아래과 같은 객체로 반환된다.

var person1 = {
  name : hodoo;
}
var person2 = {
  name : wero;
}

하나의 Person 생성자를 바탕으로 hodoo와 wero 두 객체를 만들었다. 이 객체들은 name이라는 프로퍼티를 가지고 있다.

생성자 함수의 매개변수로 들어간 변수들은 this.name에 저장된다. this는 바로 생성자 함수 자신을 가리킨다. 이렇게 this에 저장된 것들은 new를 통해 객체를 만들때 그 객체에 적용된다.


프로토타입 체인

모든 함수는 프로토타입이라는 다른 객체를 가리키는 내부 링크를 가지고 있다.
prototype 객체는 사전 그대로 원형을 뜻한다. 원래의 모습인 것이다. 같은 생성자로부터 만들어진 객체들은 모두 이 원형 객체를 공유한다. 따라서 Person의 prototype 객체에 name이라는 프로퍼티를 생성하면 Person 생성자로 만든 모든 객체는 이 프로퍼티를 공유한다.

프로토타입을 통해 직접 객체를 연결할 수 있는데 이를 프로토타입 체인이라 한다.

prototype

함수는 객체이기 때문에 key와 value를 가질 수 있다.
모든 함수에는 'prototype'이라는 속성을 가지고 있고 값으로 객체를 가지게 된다.

function foo() {};
foo.prototype; // → {constructor:foo}
foo.prototype.constuctor === foo // 생성자 함수를 가리킨다.

생성자 함수와 상관없이 모든 함수에는 'prototype', 'constrictor'라는 속성을 가지고 있다.

prototype chain

function Person (name) {
   this.name = name
}

Person.prototype.power = 100;
Person.prototype.fun = 200;
Person.prototype.love = function (a) {
  console.log(a + 20);
}

var person1 = new Person('hodoo'); // 인스턴스
var person2 = new Person('wero'); // 인스턴스

person1과 person2는 아래와 같이 반환된다.

var person1 = {
  name: 'hodoo';
}
var person2 = {
  name: 'wero';
}

person1.power;  // 100
person1.fun;  // 200
person1.love(10);  // 30

person2.power;  // 100
person2.fun;  // 200
person2.love(20);  // 40

위 코드와 같이 person1과 person2에는 power, fun, love라는 속성이 없다. 하지만 instance 객체는 생성자 함수의 prototype 속성을 사용할 수 있다. prototype을 사용하면 생성자 함수 속성에 따로 정의하지 않아도 되기 때문에 중복을 줄일 수 있다.

상속

function Grandmother (name) {
  name: name;
}

Grandmother.prototype.love = 100;

var mother = new Grandmother('mom');

var child = Object.create(mother); // mother의 prototype을 갖는 빈객체가 생성된다.

child.love;  // 100;

위 코드에서 child는 mother의 prototype을 갖는 빈객체이다.

  1. child에는 love라는 속성이 없기 때문에 상위 객체인 prototype chain을 타고 올라가 mother에서 love라는 속성을 찾는다.

  2. mother에도 love라는 속성이 없다면 mother의 상위 객체인 grandmother에 가서 love라는 속성을 찾게 된다.

  3. 속성을 찾게되면 child는 love라는 속성을 사용할 수 있다.

var arr = []; // 생성자함수 Array
Object.prototype.name = 'object';
arr.name; // 'object'
// 1. 'arr'는 'name'이라는 속성이 없다.
// 2. arr의 생성자 함수 'Array.prototype'에 가서 'name'이라는 속성을 찾는다. 
// 3. 'Array.prototype'에 'name'이라는 속성이 없기 대문에 상위 객체 'Object.prototype'에 'name'의 값을 찾아 'arr'을 사용할 수 있게 된다. 

JavaScript에서 Object.prototype은 최상위 객체이다.


2편에서 계속됩니다.

출처

링크

profile
안녕하세요 주니어 프론트엔드 개발자 양윤성입니다.

0개의 댓글