본문 바로가기

Dev.FrontEnd/JavaScript

7. 자바스크립트의 객체와 객체 멤버

Chapter 7. 자바스크립트의 객체와 객체 멤버

자바스크립트에서는 기본적으로 모든 메소드, 속성은 공개(public)으로 정의된다.
비공개(private)특징을 구현할 수는 있다.

자바스크립트에서는 객체를 만들어내는 방법이 3가지 존재한다.
1. new와 Object 생성자 이용 - new Object( )
2. 객체 리터럴 이용 - { }
이 방법은 1과 비교했을 때, 내부적인 절차는 동일하다.
즉, Object 생성자를 이용해 객체가 생성되고 { }에서 정의한 멤버를 동적으로 추가하는 것이다.
1
2
var obj = { };
var obj = new Object;
cs
위 두 코드는 동일하다.
이렇게 정의된 멤버는 모두 외부에서 접근할 수 있는 공개 멤버이다.
3. new와 사용자 정의 생성자 이용 - new Person( )
class라는 키워드 대신 function을 사용한다.

Object라는 함수는 자바스크립트에서 기본적으로 제공해주는 생성자이다.
이 같은 함수를 생성자 대신 내장 타입, 내장 객체, 내장 함수라고 부른다.
이러한 내장 함수는 사전에 정의되어 있을 뿐,
프로그램이 실행되면 내장 함수가 메모리에 정의되고
함수가 지닌 특성 그대로 지니게 된다.



함수와 클래스의 차이
우선, 클래스는 Strong Type language를 기반으로 한다.
즉, 객체의 타입만 보고도 그 객체가 어떤 구조로 되어있는지 알 수 있다.
그러나 자바스크립트에서는 함수에 전달되는 객체가
어떤 타입인지 중요하지 않고, 타입 체크도 하지 않는다.
즉, 컴파일 단계(파싱 단계)에서는 메소드의 존재 여부를 알 수 없다.

그리고 클래스로 생성된 객체의 구조는 고정적이지만
자바스크립트 객체의 구조는 런타임에 언제든지 추가, 제거, 대체될 수 있다.
따라서 자바스크립트의 생성자는 생성되는 객체의 최초 구조를 결정한다.

this를 통해 정의되는 멤버는 현재 생성되고 있는 객체의 공개 멤버로 정의된다.
그리고 new로 생성되는 인스턴스별로 별도로 존재한다.
따로 인스턴스 멤버라고 부른다.



자바스크립트 객체 멤버



생성자에 정의된 멤버를 생성자 멤버(constructor member)라 하자.
이 생성자 멤버는 함수 모델에서 공개 변수 스코프에 추가되는 멤버이다.
생성자 멤버에 접근할 때는 생성자를 통해 접근하면 된다.

그리고 생성자에서 this를 이용하여 정의하는 멤버를 인스턴스 멤버(instance member)라고 한다.
그리고 프로토타입 객체에 정의되는 멤버를 프로토타입 멤버(prototype member)라 한다.

위 세 멤버는 모두 공개 멤버(publicimember)이다.
즉, 외부 환경에서 읽기와 쓰기가 모두 가능하다.

각각 존재하는 곳이 별도로 존재한다.
생성자 멤버, 프로토타입 멤버는 함수별로 하나만 존재하고,
인스턴스 멤버는 인스턴스 별로 존재하게 된다.


데이터구조
객체별로 자신에게 속한 멤버를 관리하는 내부적인 데이터 구조가 있다.
객체의 멤버는 (key, value)의 쌍으로 구성된 집합이다.
해시구조의 일종인 연상배열(associative array)이라는 데이터 구조를 사용한다.
(key, value)의 쌍에서,
value가 함수 객체로 할당되면 해당 멤버는 메소드가 되는 것이고,
그 밖의 값으로 할당되면 속성이 된다.

일반 배열의 요소는 순차적인데 비해 연상 배열은 그렇지 않다.
그래서 요소를 검색할 때는 순차적으로 검색을 하는 것이 아니라,
내부 알고리즘에 의해 키를 기반으로 직접 해당 요소에 접근할 수 있다.
(이런 구조는 검색 속도면에서 대단히 빠르다.)

연상 배열의 요소에 접근하려고 할 때는 [ ] 연산자를 사용한다.
일반 배열과는 다르게 index 값이 아니라, key를 사용해야 하고
일반 해시와 다른 점은 키값으로 문자열만 사용할 수 있다는 것이다.
키는 값들을 구별하는 요소이기 때문에 키로 사용된 문자열은 고유해야 한다.
키의 이름은 멤버의 이름이 된다.
따라서 오버로딩 개념은 지원되지 않는다.

멤버가 연상 배열이라는 구조로 관리되기 때문에
객체지향적인 표현상으로는 속성과 메소드를 구분하지만
자바스크립트 입장에서는 속성과 메소드를 구분하지 않는다.
이런 특성 때문에 멤버이름만 보고도 이것이 속성인지 메소드인지
더 나아가 무슨 일을 하는 멤버인지 유추할 수 있게 적절한 이름을 부여하는 것이 더욱 중요하다.


속성을 추가할 때는 별도의 키워드를 사용하지 않고
마치 그 속성이 존재하는 것처럼 값을 설정하면 된다.
이 때 기존에 존재하는 속성값을 보존해야 하는 경우라면
존재 여부를 판단하는 절차를 추가해야 한다.
if( !obj.propetyA)     obj.propertyA = new Date( );
또는 메서드를 활용하는 방법이 있다/
hasOwnProperty 메서드이다.
이 메서드는 개발자가 추가한 멤버에 대해서만 작동한다.
기존에 존재하는 즉, 원래의 멤버에 대해서는 작동하지 않는다.
1
2
mycar.hasOwnProperty(“model”); => true
mycar.hasOwnProperty(“toString”); => false
cs

또 in 이라는 연산자가 있다.
이 연산자는 원래의 멤버도 연산의 대상으로 결과를 도출해낸다.
“model” in mycar; => true
“toString” in mycar; => true

in 연산자를 for문과 함께 사용하여 멤버를 순회하여 접근할 수 있다.
for(var property in obj){
     //property 사용
}
이 때는 내장 멤버에는 접근하지 않는다.
속성을 삭제할 때는 delete라는 키워드를 사용한다. 





#포스팅 내용은 황인균 님의 자바스크립트 객체지향 프로그래밍 이라는 책의 내용을 기반으로 작성되었습니다.
Chapter 7. 끝