본문 바로가기

웹개발/javascript

자바스크립트 데이터 타입 : 오브젝트 Objects

 

 

 자바스크립트 오브젝트

 

오브젝트는 자바스크립트의 데이터 타입 중 하나로 연관된 데이터들을 묶어놓은 것으로 키와 벨류로 이루어진다. 

오브젝트에는 프리미티브 타입이 들어있는데 프리미티브 타입은 변수 하나당 값을 하나만 담을 수 있고 자바스크립트에서는 클래스가 없어도 바로 오브젝트를 생성할 수 있다. 

 

const obj = {}; // 'object literal' syntax
const obj1 = new Object(); //'object constructor' syntax

function print(person) {
  console.log(person.name);      
  console.log(person.age);			
}

const bob = { name: "bob", age: 4 };
print(bob);        // bob  // 4

 

오브젝트를 만드는 것은 이렇게 직접 빈 중괄호를 통해 변수에 값을 할당해주거나 새 오브젝트를 만드는 함수를 값에 할당해 만들 수 있다. 또 함수를 통해 오브젝트를 만들어 줄 수도 있다. 

 

 

 

bob.hasjob = true;
console.log(bob.hasjob);            //true

// can delete properties later
delete bob.hasjob;
console.log(bob.hasjob);            //undefined

// 2. Computed properties
console.log(bob.name);              //bob
console.log(bob["name"]);           //bob
bob["hasjob"] = true;
console.log(bob.hasjob);            //true

function printValue(obj, key) {
  //   console.log(obj.key);
  console.log(obj[key]);        
}
printValue(bob, "name");            //bob

 

오브젝트의 프로퍼티에 접근하는 방법은 점으로도 접근이 가능하고 괄호 안에 스트링 형태로 접근이 가능하다. 

보통은 코딩하는 그 순간 그 키에 해당하는 값을 받아오고 싶을 때 점을 사용하고 

정확하게 어떤 키가 필요한 지 모를 때(런타임에서 결정될 때), 실시간으로 원하는 키를 받아오고 싶을 때 [] 괄호를 사용한다. 

 

자바스크립트는 동적인 프로그래밍 언어이다.

즉 타입이 런타임( 프로그램이 동작하고 있을때 ) 때 결정된다. 그전에 프로퍼티를 변경하는 것이 가능하며 뒤늦게 하나의 프로퍼티를 추가할 수 있다. 심지어 프로퍼티 삭제도 가능하다.

 하지만 동적으로 자유로운 만큼 유지보수에서 어려움이 있을 수 있고 생각지도 못한 에러가 발생할 수도 있기 때문에 가능하면 나중에 프로퍼티를 추가하는 것은 피하는 것이 좋다. 

 

 중요한점은 오브젝트는 "키와 밸류의 집합체이다"라는 것이다. 

 

 

 

const person1 = { name: "bob", age: 2 };
const person2 = { name: "cathy", age: 2 };
const person3 = { name: "dave", age: 30 };
const person4 = new Person("sally", 20);
console.log(person4);

function Person(name, age) {
  // this = {};
  this.name = name;
  this.age = age;
  //   return this;
}

 

  오브젝트를 필요할 때 일일이 만들게 되면 불가피하게 동일한 키와 밸류들을 반복해서 작성해야 한다. 

그래서 함수를 이용해서 값만 전달해주면 오브젝트를 만들어 주면 좋다. ES6에서는 클래스가 있어서 클래스를 사용하지만 기능적으로는 클래스와 같기 때문에 클래스가 나오기 전에는 이렇게 오브젝트를 만들었다. 

 

 오브젝트를 생성하는 함수들은 보통 대문자로 시작하도록 함수들을 만들고 리턴을 하는것이 아닌 this.name 이렇게 작성하게 된다. 그래서 위처럼 new Object로 오브젝트를 만드는 것처럼 new Person 이렇게 만들 수 있다. 이렇게 하면 자바스크립트 엔진이 알아서 오브젝트를 생성해준다. 이렇게 함수로 오브젝트를 만들 때 함수 안에 생략된 것은 this라는 새로운 프로퍼티를 만드는 부분과 디스를 반환하는 부분이다. 결국 this에 값을 할당하고 this를 반환하는 것이다.

 이것을 바로 컨스트럭터 펑션(Constructor Function)이라고 한다. 

 

 

 

console.log("name" in bob);
console.log("age" in bob);
console.log("random" in bob);
console.log(bob.random);

 

위의 코드와 이어서 이번 코드를 연결해서 보자. 

 인 오퍼레이터 (in operator)는 해당하는 오브젝트 안에 키가 있는지 없는지 확인하는 것이다. (key in obj)의 형태로 만약 해당 오브젝트 안에 키가 있다면 true를 반환하고 없다면 false를 반환한다. 그러므로 위에 콘솔 창에 출력되는 것은 차례로 true, true, false를 반환하게 된다. 마지막과 같이 만약 오브젝트에서 없는 키값으로 접근하게 되면 undefined가 출력되어 나오는 것을 확인할 수 있다. 

 

 

 

// for (key on obj)
for (key in bob) {
  console.log(key);
}

// for (value of iterable)
const array = [1, 2, 3, 4];
for (value of array) {
  console.log(value);
}

 

for... in :

 - in이라는 키워드를 쓰게 되면 오브젝트가 가지고 있는 키들이 블록을 돌 때마다 오브 벡트의 키들이 키라는 지역변수에 할당이 된다. 그래서 출력하게 되면 오브젝트 안에 모든 키들이 출력되게 된다. 

이것은 모든 키들을 받아와서 일을 처리하고 싶을 때 사용하면 좋다. 

 

for... of :

 of는 오브젝트에 쓰는 것이 아니라 배열, 리스트 이렇게 순차적으로 리터러블(literable) 한 아이들에서 사용된다. 

배열에 있는 모든 값들이 value에 할당되면서 블록 안에서 순차적으로 출력하거나 값을 계산할 수 있다. 

 

 

 

const user = { name: 'bob', age: '20' };
const user2 = user;
console.log(user); //{name: "bob", age: "20"}

// old way
const user3 = {};
for (key in user) {
	user3[key] = user[key];
}
console.log(user3); //{name: "bob", age: "20"}

let user4 = {};
Object.assign(user4, user);
const user5 = Object.assign({}, user);
console.log(user4); //{name: "bob", age: "20"}
console.log(user5); //{name: "bob", age: "20"}

// another example
const fruit1 = { color: 'red' };
const fruit2 = { color: 'blue', size: 'big' };
const mixed = Object.assign({}, fruit1, fruit2);
console.log(mixed.color); // blue
console.log(mixed.size);  // big

 

클로닝 (cloning)

 

하나의 변수에 오브젝트를 만들어 놓는다면 그 변수는 레퍼런스를 가리키게 되고 그 레퍼런스는 데이터 값이 할당된다..  다른 변수가 첫 번째 변수를 가리키게 한다면 그것은 첫번째 변수의 레퍼런스를 가리키는것과 같다. 그렇다면 두 개의 변수는 하나의 레퍼런스를 가리키고 결국 두개의 변수가 같은 데이터 값을 할당받고 있다. 그래서 두번째 변수에서 값을 변경하면 그 변수에서 가리키고있는 레퍼런스의 할당된 값,  즉 첫번째 변수에 할당된 값이 변경되어 두개의 변수 모두 같은 데이터값을 가지게 된다. 그래서 이런 것을 방지하고 복사만 하는 방법으로 두 가지의 방법이 있다. 

 

오래된 방식으로는 비어있는 오브젝트를 먼저 만들고 for in문을 통해 수동적으로 값을 넣어 복사해주는 방법이 있다. 

 

요즘에는 그렇게 보다  오브젝트의 함수인 어싸인 함수를 사용한다. 오브젝트는 자바스크립트에 기본적으로 탑재되어있고 자바스크립트의 모든 오브젝트는 오브젝트 함수를 상속하고 있기 때문에 어싸인 함수 또한 기본적으로 상속한다. 

(dest, [obj1, obj2, obj3...]) 이런 구조로 사용을 하게 되는데 첫 번째 인자로는 복사하고자 하는 타겟을 받고 그 다음부터는 복사를 하려고 하는 소스를 인자로 넣어주면 복사가 된다. 첫번째 인자로는 위와 같이 비어져있는 오브젝트를 넣어도 되고 오브젝트가 할당된 변수를 넣어주어도 된다. 만약 복사하려는 소스 오브젝트가 두 개 이상이라면 두 개가 섞여서 나오고 같은 키값을 가지고 있다면 뒤에 나오는 오브젝트일수록 값을 그위에 계속 덮어쓰게 된다. 

 

 

 


 

유튜버 드림 코딩 엘리님의 영상을 기반으로 공부한 것을 정리한 내용입니다.