[JavaScript] 객체(Object)

Noma·2021년 1월 23일
0

1. Object(객체) 란?

Object={key : value};

  • JavaScript의 데이터 유형 중 하나이다.
  • 관련 데이터와 함수의 집합이다.
  • JavaScript의 거의 모든 개체가 Object의 인스턴스이다.
  • 오브젝트는 key와 value의 집합체이다.

2. 오브젝트 생성 방법

  • Object Literal를 선언하는 방법
const obj1 = {};
  • Constructor Function을 사용하는 방법
const obj1= new FuctionName(value);
  • Object() 생성자를 사용하는 방법
const obj1 = new Object();
  • create() 함수를 사용하는 방법
const person2 = Object.create(person1);

2.1 Object Literal

: 객체를 생성할 때 컨텐츠를 그대로 대입해 생성하는 방식이다.

const objectName = {
  member1Name: member1Value,
  member2Name: member2Value,
  member3Name: member3Value
};

이름(name)과 값(value)은 ','로 분리
한 쌍의 이름과 값은 ','로 구분

< 예제 >

const merry = { 
  name: ['Merry', 'Ha'],
  age: 24, 
  gender: 'female',
  interests: ['drawing', 'music','travel'],
  greeting: function(){
  	console.log(`Hi! I'm ${this.name[0]}.`);
  }

};
print(merry); 

function print(person) {
  console.log(person.name[0]); // Merry
  console.log(person.age); // 24
  console.log(person.interests[1]); // music
  person.greeting(); // Hi! I'm Merry.
}

객체를 구성하는 멤버의 값은 어떤 것(문자열, 숫자, 배열, 함수..)도 가능

  • property (속성) : 오브젝트의 데이터 아이템
  • method (함수) : 프로퍼티를 이용해 특정 기능을 구현한 것

연속된 구조체나 연관된 데이터를 일정한 방법으로 변환하고자 할 때 많이 쓰이는 방법이다.

e.g. 서버에게 주소를 데이터베이스에 넣어달라고 요청하는 경우
각 아이템들을 하나 하나 개별 전송하는 것보다, 하나의 객체를 전송하는 것이 훨씬 효율적임

2.2 Object Constructor

const person1 = { name: "bob", age: 2 };
const person2 = { name: "steve", age: 3 };
const person3 = { name: "dave", age: 4 };

▷ object를 필요할 때마다 일일이 만들게 되면 이렇게 불가피하게 동일한 key와 value를 반복해서 작성해야하는 문제점이 있다.

object를 생성하는 함수를 만들어 보자.

const person4 = createNewPerson("ellie"); 
console.log(person4.name); // ellie
person4.greeting(); // Hi! I'm ellie.

function createNewPerson(name) {
  const obj = {};
  obj.name = name;
  obj.greeting = function() {
    console.log(`Hi! I'm ${this.name}.`);
  };
  return obj;
}

▷ 이처럼 다른 계산을 하지 않고 순수하게 object를 생성하는 함수들을 생성자 함수(Constructor Function)라고 한다.

이것은 잘 작동하지만, 썩 깔끔하진 않다. 굳이 빈 객체를 만들고 내용을 채워 리턴하지 않고 자바스크립트가 제공하는 생성자 함수의 형태의 간단한 단축 명령을 사용해보자.

관습적으로, 생성자 함수가 코드 안에서 잘 구별되도록 함수명을 대문자로 시작하는 간결한 단어로 표현한다.(createNewPerson → Person)

function Person(name) {
  // this={}; 생략됨 → 새로운 object를 만들어서
  this.name = name; // this에 name이라는 property를 생성해 name값 할당
  this.greeting = function() {
    console.log(`Hi! I'm ${this.name}.`);
  };
  // return this; 생략됨
}

이는 new키워드를 사용해 생성자 함수를 호출하여 객체를 만들 수 있다.

const merry=new Person('Merry');
  • new : 브라우저에게 우리가 새로운 객체 인스턴스를 만들고 싶어한다는 것을 알려준다. 괄호로 감싸진 매개변수들과 함께 생성자 이름을 호출하고, 결과를 변수에 담는다.

2.3 Object() 생성자

const person1 = new Object();

이는 빈 객체를 person1 변수에 담는다. 이제 이 객체에 점 표기법이나 괄호 표기법을 이용해 프로퍼티와 메소드들을 추가할 수 있다.

person1.name = 'Chris';
person1['age'] = 38;
person1.greeting = function() {
  console.log(`Hi! I'm ${this.name}.`);
};

사전에 프로퍼티와 메소드를 정의하기 위해, Object() 생성자의 파라미터로 객체 리터럴을 전달할 수도 있다.

var person1 = new Object({
  name: 'Chris',
  age: 38,
  greeting: function() {
    alert('Hi! I\'m ' + this.name + '.');
  }
});

2.4 create() 함수

객체 인스턴스들을 생성할 때 먼저 생성자를 만들기를 원하지 않을 때, 특히 그들이 적은 수의 객체만을 생성할 때 사용한다.

자바스크립트는 create()라는 내장함수를 가지고 있어, 이미 존재하는 객체를 이용해 새로운 객체를 만들 수 있다.

// 여기서의 person1은 2.3에서 만든 person1임
const person2 = Object.create(person1);
person2.name
person2.greeting()

person2가 person1을 기반으로 만들어져서, 새 객체는 원 객체와 같은 프로퍼티와 메소드들을 가진다.

3. Dynamically typed language

JS는 동적으로 타입이 Runtime(프로그램이 동작하고 있을때)때 결정되는 언어이다.

3.1 객체 멤버값 설정(갱신) 및 삭제

merry.age=30; // 갱신
merry.hasJob = true; // 새로운 멤버 설정
console.log(merry.hasJob); // true
delete merry.hasJob; // 삭제
console.log(merry.hasJob); // undefined

위의 코드와 같이, 뒤늦게 property를 추가할 수도 삭제할 수도 있다.

하지만, 이는 유지보수가 힘들고 생각치도 못한 오류를 발생시킬수 있기 때문에 가능한 피하는 것이 좋다.

4. 객체 프로퍼티 접근법

4.1 점 표기법

오브젝트 이름(merry)은 * namespace처럼 동작한다.
* namespace: 해당 객체를 참조하기 위한 이름

객체 내에 캡슐화되어 있는 것에 접근하려면 먼저 점을 찍고 접근하고자 하는 항목(프로퍼티의 이름, 배열의 일부, 객체의 메소드...)을 적는다.

merry.age
merry.interest[1]
merry.greeting()
  • 코딩하는 그 순간 키에 해당하는 값을 받아오고 싶을 때 사용
    → 평소엔 보통 dot을 쓴다.

4.1.1 하위 namespaces

객체 멤버의 값으로 또 다른 객체를 갖을 수 있다.
위의 name 멤버를 아래와 같이 바꾸면, 하위 namespace를 만들 수 있다.

name:{
    first:'Merry',
    last:'Ha'
},

사용할 때는 끝에 점을 찍으면 된다.

merry.name.first
merry.name.last

4.2 괄호 표기법

console.log(merry["name"]); 
  • 배열 속에 있는 항목에 접근하는 방법과 기본적으로 동일
  • 각 멤버의 값들과 연결된 이름(string 형태)으로 접근
  • ❗ 정확하게 어떤 키가 필요한지 모를 때 즉, 런타임에서 "동적으로" key값을 받아오고 싶을 때 사용한다.

< 방법2 - 예제 >

printValue(merry, "age"); // 24
// key는 항상 string 타입으로 전달해야 한다.

function printValue(obj, key) {
  console.log(obj[key]); 
  // key는 어떤 걸 출력해야 할지 코딩하는 이 시점에선 모른다.
}

5. in operator

: 해당 key가 object안에 있는지 없는지 알 수 있다.

key in obj

console.log("name" in ellie); // ture
console.log("age" in ellie); // true
console.log("random" in ellie); // false

6. for..in vs for..of

  • for ( key in obj )
    : merry가 가진 key들이 차례대로 지역변수 key에 할당되어 블럭{}을 돈다.
for (let key in merry) {
  console.log(key);
}
  • for ( value of iterable )
    : 배열, 리스트 같이 순차적이고 iterable한 것에 쓰인다.
const array = [1, 2, 4, 5];
for (let value of array) {
  console.log(value);
}
  • 비효율적인 for문
for(let i=0; i<array.length; i++){
    console.log(arrary[i]);
}

7. Cloning

Object.assign(target, ...sources)

  • target : 대상 개체 - sources 속성을 적용할 대상 개체로, 수정 후 반환
  • sources : 원본 개체 - 적용할 속성을 포함하는 개체
const user4 = {};
Object.assign(user4, user); 
// 빈 공간(user4)과 복사하고자 하는 object(user)를 전달하면 된다.

// 같은 의미로 밑에처럼 작성해도 OK
const user4=Object.assign({},user);

// another example
const fruit1 = { color: "red" };
const fruit2 = { color: "yellow", size: "small" };
const mixed = Object.assign({}, fruit1, fruit2); 
// 앞에 동일한 property가 있다면 뒤로 갈수록 값을 덮어 씌운다.

console.log(mixed.color); // yellow
console.log(mixed.size); // small

// Another ways
const user = { name: "merry", age: 24 };
const user2 = user; // ref 참조
user2.name = "coder";
console.log(user); // {name: "coder", age: 24} (영향 받음)
  • 오래된 방법

: 텅 빈 오브젝트를 만들어 복사

const user3 = {}; 
for (let key in user) {
  user3[key] = user[key]; 
}
console.log(user3); // {name: "coder", age: 24}

❗ 참고 자료
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics
https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Object-oriented_JS
https://www.youtube.com/channel/UC_4u-bXaba7yrRz_6x6kb_w

profile
Frontend Web/App Engineer

0개의 댓글