Javascript 객체(Object) - 기본

Javascript

Javascript의 데이터 타입(Data type)에 대해 공부할때 우리는 원시형(Primitives Type 또는 기본형)과 참조형(Reference Type) 데이터로 분류할 수 있으며 원시형을 제외한 모든 데이터 유형은 객체라고 정의했었습니다.

그렇다면 Javascript에서 객체란 무엇이며, Javascript에서의 객체 유형과 내부 속성인 property와 method에 대해서 알아보겠습니다.

객체(Objects)에 대한 기본정의

Javascript에서 객체란 Pass by Reference 분류되는 데이터 타입으로써 메모리상의 식별자(Indentifier)을 통해 참조된다. 또한 {key: value} 와 같은 키와 값이 매핑된 복합적 형태의 데이터 구조로 키는 문자열이고 값은 원시값 또는 다시 객체가 할당될 수도 있다.

Javascript 의 객체 구성요소

Javascript의 표준인 ECMAScript에서는 Object에 대해 크게 3가지로 분류하고 있습니다.

  1. Built-In Object
  2. Native Object
  3. Host Object

Built-In Object (내장 객체)

Built-In 객체 에는 Javascript 엔진이 구동되는 시점에서 즉시 제공 되는 객체로써 Global, Object, String, Number, Boolean, Date, Array, Math, RegExp, Error 가 있다.

위 객체들은 전역 객체(Global Object), 래퍼 객체(Wrapper Object), 표준 객체 (Standard Object)로 구성되어 있으며 래퍼 객체(Wrapper Object) 는 원시 타입의 프로퍼티에 접근하려고 할때 생성되는 임시 객체를 말하고, 표준 객체 (Standard Object) 는 다른 객체의 기초가 되는 핵심 객체로서 자주 사용되는 객체로는 Number , Math , Date , String , Array 가 있다.

Native Object (브라우저 내장 객체)

내장 객체와 똑같이 Javascript 엔진이 구동되는 시점에서 즉시 제공되는 객체이며 내장 객체이지만, 차이점은 브라우저마다 구성을 다르기 때문에 내장객체와 다르다고 한다. 브라우저 내장 객체로는 BOM(Browser Object Model)DOM(Document Object Model) 가 있다.

Host Object (사용자 정의 객체)

Host 객체 는 말 그대로 Host === 사용자 가 생성한 객체로, constructor 혹은 Object Literal(객체 리터럴) 방식을 사용자(혹은 개발자)가 정의하고 확장한 것으로 Built-In 객체Native Object(브라우저 내장 객체) 가 생성된 이후에 구성된다.

이번에 우리가 다루게 될 객체는 Built-In 객체 이자 최상위 레벨의 객체(Top-Level-Object)Object 객체 입니다.

객체 참조 - 프로퍼티와 메소드

우리는 객체 리터럴 방식으로 생성한 person 이라는 객체 하나를 가지고 있다.

1
2
3
4
5
6
7
8
9
10
var person = {
last: 'James',
first: 'Bond',
getLastName () {
return this.last;
},
getFirstName () {
return this.first
}
}

person 객체의 last 프로퍼티에 접근해 값을 얻고자 한다면 우리가 사용할 수 있는 방법은 두가지이다. 아래 코드를 보자.

1
2
3
4
5
6
// 점(.) 표기법
person.last // 'James'
person.getLastName() // 'James' (메소드 호출)

// 대괄호 표기법
person['last'] // 'James'

객체 이름(person)은 네임스페이스 처럼 동작하며 객체 내에 캡슐화 된 프로퍼티에 접근하기 위해서 점 표기법과 대괄호 표기법 둘다 사용 가능하며 메서드에 접근하기 위해서는 점 표기법을 사용하면 된다.

한가지 흥미로운 점은 Javascript에서 Array 요소 접근법인 대괄호 표기법이 객체에서도 사용되는 것인데 배열의 각 요소를 인덱스 숫자로 매핑하는 것과 유사하게 객체는 각 프로터피를 {key: value} 구조로 매핑하며 따라서 객체에서도 한 프로퍼티에 접근하기 위해 대괄호 표현법에서 프로퍼티의 key를 사용할 수 있는 것입니다. 이러한 점 때문에 객체가 간혹 연관배열 (associative arrays) 이라고 불리며 배열이 숫자를 값에 연결하는 것과 같은 방법으로 스트링을 값에 매핑합니다.

객체 생성자

우리는 Javascript 코드로 크고 작은 기능들을 개발하면서 수 많은 객체를 생성하게 된다. 이 객체들은 Built-In 객체Object 객체인스턴스(instance) 입니다. 그럼 객체를 생성하는 방법으로는 위에서 사용하는 리터럴 방식 외에는 무엇이 있을까?

리터럴 표기법을 통한 객체 생성

Javascript에서 객체를 생성하기 위한 가장 일반적이고 쉬운 방법으로 프로퍼티와 메소드를 직관적으로 설정할 수 있다.

1
2
3
4
5
var cat = {
name: '나비',
age: 3,
family: 'korean Short Hair'
}

생성자 함수 (Constructor function)을 통한 객체 생성

Javascript에서는 new 연산자를 사용하여 객체를 생성하고 초기화할 수 있는데 이때 사용되는 메소드를 생성자(constructor) 라고 하며, 이 메소드는 새롭게 생성되는 객체를 초기화하는 역할을 합니다.

1
2
3
4
5
6
7
8
9
 // Cat에 관한 생성자 함수
function Cat (name, age, family) {
this.name = name; // name에 관한 프로퍼티
this.age = age; // age에 관한 프로퍼티
this.family = family; // family에 관한 프로퍼티
}

// cat 객체는 Cat라는 프로토타입을 갖게 된다.
var cat = new Cat('나비', 3, 'korean Short Hair')

Object Create() 메소드를 통한 객체 생성

Object.create() 메소드는 지정된 프로토타입(prototype) 객체와 프로퍼티를 가지는 새로운 객체를 생성할 수 있으며 사용자가 프로토타입 객체를 직접 명시할 수 있다는 특징이 있다.

1
2
3
4
5
var cat = Object.create(null, {
name: '나비',
age: 3,
family: 'korean Short Hair'
});

프로퍼티와 메소드 그리고 this

아래의 person 객체를 보자. 코드를 훓어보면 대략 사람의 이름이 설정되어 있는것으로 추측할 수 있으며 그 속성을 반환(return) 하는 함수들이 있다는 정도로 추측 또는 알 수 있다. 바로 사람의 이름과 같은 속성을 프로퍼티(property) , 속성을 반환(return) 하는 함수를 메소드(method) 라고 한다.

1
2
3
4
5
6
7
8
9
10
var person = {
last: 'James',
first: 'Bond',
getLastName () {
return this.last;
},
getFirstName () {
return this.first
}
}

프로퍼티 (Property)

프로퍼티란 객체에 붙은 변수(Variable) 로써 프로퍼티가 객체의 속성을 규정한다고 할 수 있다. 프로퍼티와 변수는 기본적으로 똑같으며 프로퍼티의 이름은 대소문자를 구별 하며 객체 이름 또한 해당되며 Javascript의 문자열 또는 문자열로 변환 가능한 어떤 것도 가능하나 빈 문자열('')의 경우 가능은 하나 Javascript의 식별자(Indentifier)로써 적합하지 않다(- , '', 숫자로 시작하는 이름도 해당).

메소드 (Method)

메소드란 객체의 프로퍼티 중 함수인 것으로 일반 함수와 같은 방식으로 정의할 수 있다. ECMAScript 6 부터 더 짧은 구문으로 메서드를 정의할 수 있게 됐다.

1
2
3
4
var obj = {
foo: function() {},
bar: function() {}
};
1
2
3
4
var obj = {
foo() {},
bar() {}
};

주의할 점 은 단축 구문은 기명(named) 함수로 정의해야한다. 왜냐하면 메모리에서 함수를 참조하기 위한 식별자(Identifier)가 생기기 때문입니다.

this

Javascript에서 this 는 함수가 실행될 때 this가 호출되고 있는 함수 또는 객체의 스코프를 가리키는 키워드로써, 객체 메서드 내부의 this 는 객체를 가리킨다. 본 섹션의 person 객체의 메서드에서 호출하고 있는 this 키워드가 그 예이다.

getter 와 setter 메소드

getter 메소드 는 특정 프로퍼티의 값을 받아오기 위한 메소드이자 접근자 프로퍼티 이며 setter 메소드 는 특정 프로퍼티의 값을 설정하기 위한 메소드로 ECMAScript 5 에 정의되었다.

getter 메소드

get 구문은 어떤 프로퍼티에 접근할 때마다 해당 프로퍼티의 값을 계산해 반환하거나 내부 변수의 상태를 명시적인 함수 호출없이 보여주고 싶을때 사용할 수 있다.

1
2
{get prop() { ... } }
{get [expression]() { ... } }

위 구문에서 prop 은 주어진 함수를 바인딩할 프로퍼티의 이름이고, [expression] 은 ES6부터 함수의 이름을 계산(computed) 하기 위한 표현식을 사용할 수 있다. get 구문을 이용할 떄는 다음을 유의해야 한다.

기본적인 사용법은 아래와 같다.

1
2
3
4
5
6
7
8
var obj = {
log: ['example','test'],
get latest() {
if (this.log.length == 0) return undefined;
return this.log[this.log.length - 1];
}
}
console.log(obj.latest); // "test"

setter 메소드

set 구문은 특정 프로퍼티의 값을 변경하기 위해 함수를 실행하기 위해 사용한다.

1
2
{set prop(val) { . . . }}
{set [expression](val) { . . . }}

위 구문에서 prop 은 주어진 함수를 바인딩할 프로퍼티의 이름이고, val 은 prop에 설정될 값을 가지고 있는 변수명이다. [expression] 은 ES6 부터 추가된 세부 문법으로 주어진 함수에 바인딩 되는 프로퍼티의 이름을 계산(computed) 을 통해 얻을 수 있다.

그리고 주의할 점은 실제 값을 가지는 프로퍼티와 프로퍼티의 setter 를 동시에 갖는 것은 불가능하다. 왜냐하면 Setter는 유사 객체(pseudo property) 타입을 생성하는 메소드이기 때문이며 getter 또한 동일하다. set 문법을 사용할 때 다음을 유의한다:

기본 사용법은 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
var cat = {
set currentSnack (snack) {
this.snacks[this.snacks.length] = snack;
},
snacks: []
}

cat.currentSnack = '달고나' // 달고나
cat.snacks // ['달고나']
cat.currentSnack = '커피' // 커피
cat.snacks // ['달고나', '커피']
cat.currentSnack // undefined

cat 객체의 유사 객체(pseudo property)로 currentSnack 이 정의되었으며 이 프로퍼티의 매개변수인 snack 이 설정될 때마다 snacks 프로퍼티의 값이 갱신된다.


참조