반응형

 

자바스크립트에서 객체를 생성하는 3가지 방법

 

    1. 객체 리터럴 이용하기

    2. Object() 객체 생성자 함수 이용하기

    3. 생성자 함수 이용하기

 

자바스크립트에서 객체를 생성하는 방법은 위와 같이 3가지 방법이 있습니다. 다음은 각 방법별로 실제 코드를 어떻게 쓰는지 보겠습니다.

 

 

1. 객체 리터럴 이용하기

 

객체 리터럴이란 객체의 property, value를 명시하여 생성하는 표기법입니다. 객체 리터럴로 객체를 만드는 방법은 다음과 같습니다.

 

var obj = {
    property1 : value1,
    property2 : value2
}

 

객체에는 속성(property)과 속성에 담는 값(value)을 담을 수 있습니다. 이 값에는 원시 데이터 타입인 숫자, 문자열, 불리언, null 등도 담을 수 있고 참조 데이터 타입인 객체(배열, 함수, 객체)도 담을 수 있습니다.

모든 값을 담을 수 있다고 볼 수 있습니다.

 

 

2. Object() 객체 생성자 함수 이용하기

 

var obj = new Object();
console.log(obj); // {}

 

간단하게 Object를 생성하여 변수에 담았습니다. 위와 같이 생성하면 빈 객체가 생성됩니다. 이후 property를 CRUD(생성, 읽기, 수정, 삭제) 할 수 있습니다.

 

또한 객체를 생성할 때 처음부터 초기값을 넣어주기 위해 리터럴을 함께 사용할 수 있습니다.

 

var obj = new Object({ property: "abc" });
console.log(obj); // {property: "abc"}

 

 

3. 생성자 함수 이용하기

 

생성자 함수로 객체를 만드는 방법은 조금 복잡합니다. 생성자 함수를 따로 만들고 그것을 이용해 객체를 만드는 방법이기 때문입니다. 생성자 함수란 객체를 만드는 역할을 하기 위해 만들어진 함수입니다. 생성자 함수를 이용하면 공장에서 물건 찍듯이 쉽게 원하는 객체를 반복해서 만들 수 있습니다. 예시를 보겠습니다.

 

function Person(){};
var me = new Person();

 

Person()이라는 생성자 함수를 이용해 me라는 빈 객체를 만들었습니다. 그런데 빈 객체를 만들기 위해 이렇게 복잡한 방법을 쓰지는 않겠죠. 생성자 함수를 이용하면 다음과 같은 일이 가능해집니다.

 

//생성자함수 Person()
var Person = function (name, region){
    this.name = name;
    this.region = region;
    this.introduce = "My name is " + this.name + " and My region is " + this.region + ".";
}

//객체 생성하기
var me = new Person("cocoder", "Seoul");
var you = new Person("yoon", "Seoul");

console.log(me);
console.log(you);

 

* 결과

 

위에서부터 me, you의 출력 결과

 

introduce 프로퍼티(이제부터 property의 한글 발음 그대로 쓰겠습니다.)의 값에 해당하는 자기소개 기능의 텍스트 문장을 반복해서 작성할 필요가 없습니다. 같은 기능을 하지만 서로 다른 객체를 생성자 함수를 이용해 간단하게 반복적으로 만들어내고 있습니다.

 

생성자 함수명의 첫 글자는 대문자로 사용하는 것이 좋습니다. 일종의 규칙(convention)인데 이것을 지킴으로써 코드의 가독성을 더 높일 수 있습니다. 2번 방법에서 사용한 Object함수 역시 생성자 함수입니다.

 

 

생성자 함수 내의 this가 가리키는 대상

 

생성자 함수 내에 있는 this는 생성자 함수로 생성한 객체를 가리킵니다.

따라서 me 객체를 만들 때 생성자 함수 Person() 내의 this는 me 객체에 바인딩되고

you 객체를 만들 때 생성자 함수 Person() 내의 this는 you 객체에 바인딩됩니다.

 

 

리터럴 방식과 생성자 함수 방식의 프로토타입 차이

 

객체 리터럴을 이용해서 생성한 객체의 프로토타입 객체는 Object.prototype입니다.

그런데 생성자 함수를 이용해서 생성한 객체의 프로토타입 객체는 생성자 함수의 prototype 객체인 Person.prototype입니다. 다시 말해 생성자 함수로 만든 인스턴스 me와 you의 프로토타입 객체는 Person.prototype입니다.

그리고 Person.prototype의 프로토타입 객체는 Object.prototype입니다. 이것을 프로토타입 체이닝이라고 합니다. 모든 객체는 프로토타입 체이닝을 하면 결국 마지막에 Object.prototype에 도달합니다.

 

 

this와 prototype에 대해서는 따로 또 자세히 다루는 포스팅을 할 기회가 있으면 좋겠습니다.

 

 

 

 

 

 

객체의 속성(property)에 대해 CRUD 하는 방법

 

객체를 생성하는 방법을 알았으므로 이제 생성된 객체의 프로퍼티를 어떻게 추가하고(Create), 읽어오고(Read), 수정하고(Update), 삭제(Delete)할 수 있는지에 대해서 다뤄보겠습니다.

 

우선 객체를 생성해줍니다. name이라는 프로퍼티와 값을 함께 생성했습니다.

 

var cocoder = {
    name : 'cocoder';
}

 

 

1. 객체 프로퍼티 읽기

 

객체 프로퍼티에 접근할 수 있는 두 가지 방법이 있습니다. 바로 []표기법과 .표기법입니다. 위에서 객체 cocoder를 만들고 name 프로퍼티를 만들었는데, name 프로퍼티를 두 가지 방법으로 접근해보겠습니다.

 

* []표기법

console.log(cocoder["name"]); // "cocoder"

 

* .표기법

console.log(cocoder.name); // "cocoder"

 

객체에 없는 프로퍼티를 참조하면 undefined가 뜹니다.

 

console.log(cocoder.hobby); // undefined

 

 

2. 객체 프로퍼티 갱신

 

마치 변수에 새 값을 할당해주듯이 값을 넣어주면 됩니다.

 

* []표기법

cocoder["name"] = "me";
console.log(cocoder.name); // "me"
console.log(cocoder["name"]); // "me"

 

* .표기법

cocoder.name = "me";
console.log(cocoder.name); // "me"
console.log(cocoder["name"]); // "me"

 

 

3. 객체 프로퍼티 추가

 

처음에 객체를 선언했을 때 있는 프로퍼티만 갱신할 수 있는 것이 아닙니다. 객체는 한번 선언한 이후로 새로운 프로퍼티를 계속 추가할 수 있습니다. 방법은 프로퍼티 갱신 때와 같습니다. []표기법이나 .표기법으로 새 프로퍼티명을 만들어서 값을 넣어주면 됩니다.

 

* []표기법

cocoder["hobby"] = "piano";

 

* .표기법

cocoder.hobby = "piano";

 

 

4. 객체 프로퍼티 삭제

 

프로퍼티 삭제는 delete연산자로 하면 됩니다. delete연산자는 프로퍼티만 삭제할 뿐 객체 자체를 삭제하지는 못합니다.

delete 연산자로 hobby 프로퍼티를 삭제해보겠습니다.

 

* hobby 프로퍼티 삭제

delete cocoder.hobby;
console.log(cocoder.hobby); // undefined

 

 

 

 

 

자바스크립트의 객체는 참조 데이터 타입입니다.

 

객체가 참조 데이터 타입이기에 가지는 특징들에 대해 정리를 해보겠습니다.

객체 A를 정의한다는 것은 객체 A가 독자적으로 데이터를 가지고 있다는 의미가 아니라 어느 동떨어진 외딴곳에 데이터가 형성되었고 객체 A가 그 데이터를 참조한다는 의미입니다. 이를 그림으로 표현하면 다음과 같습니다. 

 

var objA = {
    property: value;
}

 

객체 A를 정의하면 실제 데이터를 가지고 있는 익명 객체를 참조한다.

 

객체 A를 정의한 이후, 객체 B에 객체 A를 할당하면 객체 B는 객체 A를 참조합니다. 그리고 객체 A를 참조하는 것은 이중 종속으로 객체 A가 참조하고 있는 가상의 익명 객체를 참조하는 것과 같습니다. 이를 그림으로 표현하면 다음과 같습니다.

 

var objA = {
    property: value
};
var objB = objA;

 

객체B는 객체A를 참조하므로 객체B가 참조하고 있는 실제 데이터는 익명 객체가 가지고 있는 데이터다.

 

객체 A와 객체 B는 동일한 데이터를 참조하고 있습니다. 이런 경우 객체 A나 객체 B 중 하나만 수정해도 (새로 생성하는 것이 아닌 있는 객체를 수정하는 것을 의미합니다.) 그것은 그들이 참조하고 있는 익명 객체를 수정한 것과 같기 때문에 객체 A와 객체 B 둘 다 수정한 것과 같은 효과가 발생합니다.

 

* 객체 A와 객체 B가 같은 객체를 참조할 때 해당 객체의 property를 수정하는 경우

//동일한 익명 객체를 참조하는 객체 A와 객체 B 생성
var a = {
    val : 1
};
var b = a;
console.log(a.val); //1
console.log(b.val); //1

//객체 A를 수정하면 객체 B도 같이 수정된다.
a.val = 2;
console.log(a.val); //2
console.log(b.val); //2

//객체 B를 수정하면 객체 A도 같이 수정된다.
b.val = 3;
console.log(a.val); //3
console.log(b.val); //3

 

이번에는 실질적으로 같은 값을 갖는 데이터를 각각 다른 리터럴로 객체 A와 객체 B를 생성해보겠습니다.

 

* 객체 A와 객체 B를 각자 리터럴을 이용해 동일한 데이터를 넣어서 생성

var objA = {
    val : 1
};
var objB = {
    val : 1
};

 

이런 경우에는 객체 A가 참조하는 익명 객체와 객체 B가 참조하는 익명 객체는 별개의 것입니다. 왜냐하면 각자 따로 리터럴을 작성했기 때문입니다. 두 리터럴이 똑같이 생긴 것과 별개로, 저 두 데이터는 서로 다른 메모리에 서로 다른 익명 객체에 저장됩니다. 따라서 객체 A를 수정해도 객체 B는 변하지 않고 객체 B를 수정해도 객체 A는 변하지 않습니다.

 

* 객체 A와 객체 B를 각각 수정해보기

// 객체 A를 수정해도 객체 A는 변하지 않는다.
objA.val = 2;
console.log(objA.val); //2
console.log(objB.val); //1

// 객체 B를 수정해도 객체 A는 변하지 않는다.
objB.val = 3;
console.log(objA.val); //2
console.log(objB.val); //3

 

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기