IM Sprint 시리즈는, 코드 스테이츠의 웹 개발 심화 코스인 Immersive 코스에서 수강생들과 함께 이야기 나눌 주제에 대해 빠르게 학습하고 정리한 글이다.
프로그래밍 언어에는 절차 지향적 언어와 객체 지향적 언어가 있다. 자바스크립트는 객체 지향적 언어인데, 객체 지향이란 무엇일까?
객체 지향 프로그래밍이란 프로그래밍 디자인 철학 중 하나로, 모든 요소를 'Object'로 다루는 방법이다. 이는 사람이 세계를 바라보고 이해하는 방법을 흉내낸 방법론이다.
Object란, 어떤 사물 혹은 개념 그 자체이다. 객체 지향 프로그래밍은 Object가 가진 속성들 - 크기, 색상, 이름이나 동적인 '달린다'라는 움직임등 - 을 토대로 큰 틀을 만들어 그 틀을 이용해 그와 비슷한 다른 Object들을 생성할 수 있도록 설계한다.
여기서 그 틀은 class, 그를 토대로 만들어진 object를 인스턴스라 말한다. 인스턴스를 만들 때엔 class를 기반으로 요소들을 추가, 변경, 삭제하여 필요한 모양을 만든다.
OOP에는 네 가지 컨셉이 있다.
var Car = function(position) {
var someInstance = {};
someInstance.position = position;
someInstance.move = function() {
this.position = this.position + 1;
}
return someInstance;
}
var car1 = Car(5);
car1.move();
car1.move();
car1.move();
// move()함수를 3번 실행
console.log(car1);
// { position: 8, move: [Function] }
아래 코드는 extend
함수를 통해 someMethods
에 있는 메서드에 접근하도록 1번의 코드를 변형하였다. 이렇게 구성하면 Car
의 인스턴스를 만들었을 때, 인스턴스들이 someMethods
에 담긴 함수를 참조하므로 someInstace
에 모든 속성을 넣어 인스턴스를 만든 경우보다 메모리를 적게 차지한다.
var extend = function(to, from) {
for (var key in from) {
to[key] = from[key];
}
};
var someMethods = {};
someMethods.move = function() {
this.position = this.position + 1;
};
someMethods.run = function() {
this.position = this.position + 10;
}
var Car = function(position) {
var someInstance = {
position: position
};
extend(someInstance, someMethods);
return someInstance;
}
var car1 = Car(5);
car1.move();
car1.move();
car1.run();
console.log(car1);
// { position: 17, move: [Function], run: [Function] }
Object.create()
를 이용하는 방법. 여기서는 someMethods
객체를 프로토타입으로 삼는 객체를 생성했다.
var someMethods = {};
someMethods.move = function() {
this.position = this.position + 1;
};
someMethods.run = function() {
this.position = this.position + 10;
}
var Car = function(position) {
var someInstance = Object.create(someMethods);
someInstance.position = position;
return someInstance;
}
var car1 = Car(5);
car1.move();
console.log(car1);
// { position: 6 }
가장 많이 사용되는 방법. prototype
에 공통적으로 사용할 함수나 속성들을 지정하여 모든 인스턴스에서 사용한다. 이 때는 new
키워드로 인스턴스를 생성한다.
var Car = function(position) {
this.position = position;
};
Car.prototype.move = function() {
this.position = this.position + 1;
}
var car1 = new Car(5);
car1.move();
console.log(car1);
// Car { position: 6 }
자바스크립트는 class가 아닌 prototype을 기반으로 상속과 비슷한 효과를 구현한다.
생성자 함수(위에서 class로 칭한 '틀'역할)가 언어 구조적으로 가지고 있는 'prototype'에 속한 속성들은, 생성자 함수를 통해 만들어진 모든 인스턴스들이 접근할 수 있다.
그리고 자바스크립트의 모든 객체들은 'Object' object이기 때문에, 'Object' object 가진 prototype의 속성들을 모든 객체들이 접근하여 사용할 수 있다. Object는 모든 객체들의 조상과도 같다.
예를 들어 Array()
생성자를 이용해서 생성한(혹은 arr = [1, 2]
라고 적어 생성한) 배열은 Array.__proto__
에 속한 모든 속성들에 접근할 수 있다. 그리고 Array()
생성자는 Object
이므로, Object.__proto__
의 속성 역시 가지고 있다. 그래서 배열 arr
역시 Object.__proto__
에 속한 속성들에 접근 가능하다.
const arr = [1,2]
console.dir(arr);
// 콘솔에서 내용을 확인하면, arr의 __proto__가 Array(0)임을 확인할 수 있다.
// 그 탭을 열어 Array(0)의 __proto__를 확인하면, Object이다.
// 그 탭을 열면 Object.__proto__에 속한 메서드의 목록을 볼 수 있다.
// 그 중 Array.__proto__에는 없는, hasOwnProperty() 를 arr에 사용한다면?
console.log(arr.hasOwnProperty(1));
// true