티스토리 뷰
이 글은 Opentutorials.org의 생활코딩 Javascript 객체 지향 프로그래밍을 수강한 후 정리한 내용입니다.
객체에 접근하기
const member = {
developer : 'kim',
designer : 'lee',
CEO : 'park'
};
- 점표기법 :
member.developer
- 괄호표기법 :
member['developer']
- (참고) 객체 삭제하기 :
delete member.developer
, 실행 결과에 따라true
또는false
반환
(참고) var, let, const
var
- 같은 이름으로 재선언 가능
- 선언과 초기화를 한 번에 함
- 관리가 어려움
let
- ES6부터 이용 가능
- 재선언 불가능, 재할당 가능
- 선언 이전에 참조 불가(초기화되기 전까지 Temparal Dead Zone에 위치함)
- 선언과 초기화를 따로 함
const
- ES6부터 이용 가능
- 재선언 불가능, 재할당 불가능
- 선언 이전에 참조 불가(초기화 되기 전까지 Temparal Dead Zone에 위치함)
- 선언과 동시에 할당해야 함
- 함수나 객체를
const
로 선언하면 해당 자료형을 유지함. 식별자나 프로퍼티명으로 접근하여 값을 변경하는 것은 가능함
객체 조회하기
for(let position in member) {
console.log(position, member[position]); // 이 경우 점 표기법은 사용할 수 없다
}
// 실행결과
developer kim
designer lee
CEO park
내장객체 Math
Math.PI; // 3.141592653589793
Math.random(); // 0이상 1미만 부동소숫점 의사 난수 반환
Math.floor(3.9); // 3(버림)
this
JavaScript에서 전역 스크립트나 함수가 실행될 때 실행문맥(Excution Context)이 생성된다. (실제 실행은 브라우저 내의 stack에 올라가서 실행됨) 모든 context에는 참조하고 있는 객체(thidBinding)가 존재하며, 이를 알기위해 this를 사용할 수 있다.
- 객체 내에서 this는 그 객체 자신을 가리킴
- bind(), call(), apply()를 사용하여 this를 조작할 수 있음
const person = {
name: 'kim',
first: 10,
second: 20,
sum: function(f, s) {
return this.first + this.second;
}
}
console.log(person.sum()); // 30
constructor function
constructor
는 class내에서 객체를 생성하고 초기화하기 위한 특별한 메서드이다. Javascript의 모든 객체는 constructor
라는 프로퍼티를 가지며 객체의 constructor
는 자기 자신을 만든 함수를 가리킨다.
예시 1
function Person(name, age) {
this.name = name;
this.age = age;
this.getInfo = function() {...};
}
const person1 = new Person('kim', 25);
위와 같은 방식으로 100개의 객체를 생성한다면 완벽히 똑같은 동작을 하는 getInfo
함수가 100개 생성될 것이다. 어떻게 개선할 수 있을까?
예시 2 - prototype
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.getInfo = function() {...};
const person1 = new Person('kim', 25);
Person
객체를 만들면 내부적으로 Person
을 constructor로 가지는 Person.peototype
이라는 객체가 생겨난다. 이곳에 getInfo
라는 함수를 만들어두면 Person
을 이용하여 생성한 모든 객체가 하나의 Person.peototype
를 참조하여 getInfo
를 이용할 수 있게 된다. 결과적으로 getInfo
가 중복해서 생성되는 문제가 해결된다. (prototype에 대한 더 자세한 설명은 아래에 계속)
class
class는 객체를 만드는 공장
각 사람의 이름과 첫 번째, 두 번째 점수를 저장하고 총점을 반환하는 메서드를 가진 클래스를 만들었다. Java의 클래스와 비슷한 모습이다.
class Person {
// 생성자
constructor(name, first, second) {
this.name = name;
this.first = first;
this.second = second;
}
// 메소드
sum() {
return this.first + this.second;
}
}
상속과 super
만약 일부 몇 명만 세 번째 점수를 기록해야 할 필요가 생기면 어떻게 해야 할까? 기존에 작성한 Person
을 상속받는 자식 클래스에서 super
를 사용하면 부모 클래스인 Person
의 작업을 가져올 수 있다.
class PersonPlus extends Person {
constructor(name, first, second, third) {
super(name, first, third);
this.third = third;
}
sum() {
return super.sum() + this.third;
}
// PersonPlus만의 새로운 메소드를 만들 수도 있다!
avg() {
return (this.first + this.second + this.third) / 3;
}
}
Java와 같은 객체지향 언어에서는 super class의 기능을 물려받기 위해서는 sub class가 super class의 자식이 된다. 이후 sub class를 통해 어떤 객체를 만들면 그 객체가 어떤 기능을 가질 것인지는 super class와 sub class에 의해 즉 class단에서 결정된다. 생성된 객체는 이후 다른 클래스를 상속받거나 할 수 없다. 하지만 Javascript의 상속은 이와 같지 않다.
Java에서 상속은 클래스 사이의 일이었다면 Javascript에서는 sub객체가 super객체의 기능을 직접 상속받을 수 있다. 또한 상속관계의 두 객체 사이의 prototype link를 수정하면 객체 생성 이후에 상속관계를 변경하는 것도 가능하다. 이때, sub객체의 prototype link가 가리키는 객체를 prototype object라고 한다.
객체 간 상속
__proto__
const superObj = {superVal: 'super'};
const subObj = {subVal: 'sub'};
subObj.__proto__ = superObj;
__proto__
를 이용하면 객체 간에 직접 상속을 구현할 수 있다. 모든 객체는 생성될 때 __proto__
속성을 가지며, 이는 객체가 생성될 때 조상이었던 함수의 prototype object를 가리킨다. 따라서 subObj.__proto__ = superObj;
는 subObj
의 prototype link가 superObj
를 향하게 즉 상속을 받게 한다.
하지만 __proto__
는 대부분 지원하긴 하나 표준은 아니다. Javascript에서 표준으로 인정하는 방법은 아래와 같다.
Object.create()
const superObj = {superVal: 'super'};
const subObj = Object.create(superObj);
subObj.subVal = 'sub';
이는 위의 __proto__
를 이용한 코드와 같은 기능을 한다.
prototype / __proto__
// 1
function Person(name, first, second) {
this.name = name;
this.first = first;
this.second = second;
}
// 2
Person.prototype.sum = function() {
return this.first + this.second;
}
// 3
const kim = new Person('kim', 10, 20);
const lee = new Person('lee', 10, 10);
// 4(① -> ② -> ③)
console.log("kim.sum()", kim.sum());
1
Person 객체를 만들면 내부적으로 Person의 prototype객체(Person's Prototype)가 함께 만들어진다. Person객체의 prototype은 Person's Prototype를 가리키고, Person's Prototype의 constructor
는 Person객체를 가리 킨다. 이때, Person's Prototype의 __proto__
는 최상위 객체인 Object(Javascript 기본 요소)의 Prototype을 가리킨다. 이처럼 __proto__
를 통해 상위 객체로 연결되는 구조를 Prototype Chain이라고 한다.
2
Person을 이용해 새로운 객체를 생성할 때마다 중복된 sum함수가 생성되는 것을 방지하기 위해 Person's Prototype에 sum함수를 만든다. 이때, sum함수는 Constructor Function이다.
3
new
키워드를 이용하여 객체를 생성한다.
4
new Person()
을 이용하여 생성한 객체kim
에서 sum함수를 호출하면 어떤 일이 일어날까?
① 우선 kim
객체에 sum함수가 존재하는지 확인한다.
② 존재하지 않는다면 __proto__
를 통해 상위 객체로 이동한다.
③ sum함수가 존재하는지 확인한다 -> 함수를 찾았다!
이와 같이 상위 객체로 이동하며 해당 함수가 존재하는지 찾는다. 만약 최상위 객체까지 이동했는데도 해당 함수를 찾지 못한다면 오류가 발생한다.
참고 사이트