자바스크립트의 Object(객체)

Dohyeon Kong·2024년 3월 26일
0

JavaScript🟡

목록 보기
6/13
post-thumbnail

객체

객체란 자료형의 관점에서 키(Key)와 값(Value)으로 구성된 속성(Property)의 집합을 의미한다.
원시 타입(숫자, 문자열, boolean, null, undefined, Symbol)을 제외한 나머지 값들을 의미한다.

  • 객체는 자바스크립트에서 제공하는 기본 자료형과는 다르게 여러 개의 값을 가질 수 있고, 다른 자료형의 값도 가질 수 있다.
  • 객체를 생성할 때는 { }를 이용하여 생성할 수 있으며 이러한 방식은 리터럴(Literal)방식으로 객체를 생성했다고 표현한다.
// 속성이 하나도 없는 객체(=빈 객체)
const peron = {};
// 속성을 지정한 객체
const person = {
  name : "Hong Gildong"
};
// 객체는 데이터의 종류를 가리지 않고 모든 자료형의 데이터를 값는다.
const person = {
	name : ["Hong", "Gildong"], // 배열 데이터
    age : 20, // 숫자 데이터
    isAdult : true //논리 데이터
};
// 객체 안에 또 다른 객체나 함수가 들어간다.
const person = {
  name : {
      firstName : "Gildong",
      lastName : "Hong"
  },
  age : 20,
  isAdult : true,
  printInfo : function(){
   	console.log('printInfo'); 
  }
};

Property(속성)

  • 객체(object)안에 속한 변수 또는 값
  • person object는 3가지의 property를 가지고 있다. (firsName, latName, age)
var person = {
  firstName : "John",
  lastName : "Doe",
  age : 30
};
console.log(person.firstName); // "John" 출력
console.log(person.lastName); // "Doe" 출력
console.log(person.age); // 30 출력

객체 속성 다루기

  • 객체 속성에 접근하는 방법은 두 가지 접근 방법이 존재한다.
  • 대괄호 연산자마침표 연산자로 객체의 속성에 접근이 가능하다

대괄호 연산자로 접근하기

  • [ ]를 사용해 객체의 속성에 접근하는 방법으로, 배열에서도 사용이 가능하다.
  • 객체의 속성에 접근하기 위해서는 객체명 뒤에 대괄호를 붙이고 대괄호 안에 키를 넣는다.
  • 키는 큰따옴표("") 혹은 작은다옴표('')로 감싼 문자열 형태로 작성해야 한다.
// 대괄호 연산자로 객체 속성 접근하기
const person = {
  name : "Hong Gildong",
  age : 20
};
console.log(person["name"]); // Hong Gildong
console.log(person["age"]);  // 20
  • 따옴표를 생략하고 키를 작성하면 객체에서 키가 아닌 name이라는 변수를 찾게 되어 오류가 발생한다.
// 따옴표 생략시 발생하는 오류
const person ={
 name : "Hong Gildong" 
};
console.log(person[name]);
// Error 발생 : RefrenceError : name is not defined
  • 객체의 속성값이 배열이나 객체 리터럴, 함수인 경우 접근하는 방법
// 객체의 속성값이 배열이나 객체 리터럴 함수인 경우 접근하는 방법
const person = {
  name : {
    firstName : "Gildong",
    latName : "Hong"
  };
  likes : ["apple", "samsung"],
  printHello : function(){
    return "Hello";
  }
};

// person객체의 name 속성에 값으로 할당된 객체의 firstName 속성에 접근한다.
console.log(person["name"]["firsName"]);

// 대괄호 연산자에 키를 사용하여 배열인 속성값에 접근한다.
console.log(person["likes"]); // ['apple', 'samsung']

// 배열 요소를 인덱스로 접근한다.
console.log(person["likes"][0]); // apple
console.log(person["likes"][1]); // samsung

// 함수를 접근한다
console.log(person["printHello"]); // [Function : printHello]

// 함수 호출시 ()를 사용한다.
console.log(person["printHello"]()); // hello

마침표 연산자로 접근하기

  • . 를 이용하여 객체 속성에 접근한다.
  • 객체 속성에 접근하기 위해서는 접근할 객체명과 함께 객체 속성의 키를 마침표 연산자로 연결한다.
const person = {
  name : {
    firstName : "Gildong",
    latName : "Hong"
  };
  likes : ["apple", "samsung"],
  printHello : function(){
    return "Hello";
  }
};

console.log(person.name.lastName); // Hong
console.log(person.age);  // 20
console.log(person.likes[0]); // apple 
console.log(person.printHello()); // hello
  • 마침표 연산자를 사용할 때 키를 바로 적어야 하며 키를 큰따옴표나 작은따옴표로 감싸면 오류가 발생한다.
const person = {
  name : "Hong Gildong"
};
console.log(person."name");
//SystaxError : unexpected string
  • 객체 키 식별자에 공백이 있으면 마침표 연산자를 사용하지 못하고 대괄호 연산자로만 접근할 수 있다.

객체 속성 동적으로 변경하기

const person = {
  name : "Hong Gildong",
};
person.name = "Kim"; // 또는 person["name"] = "Kim";
console.log(person.name); // Kim
  • 객체로 정의된 값을 바꾸고 싶다면 키로 속성에 접근하여 값을 재할당하면 된다.

객체 속성 동적으로 추가하기

// 객체 속성 추가(1)
const person = {};
console.log(person); //{}
person.name = "Hong Gildong";
console.log(person); // {name : 'Hong Gildong'}
  • 객체 속성에 값을 할당해 접근하면 해당 속성이 있는지 확인하고, 없는 속성이라면 해당 키와 값으로 구성된 새로운 속성을 객체에 추가한다.
  • 결국 객체 식별자와 키에 마침표 연산자를 사용하면 객체의 속성에 접근하게 되고 속성에 접근해서 할당 연산자로 값을 할당하면 값이 변경되거나 새로운 속성이 추가된다.
// 객체 속성 추가(2)
const person = {};
console.log(person); //{}
person.name = {
 firstName : "Gildong",
 lastName : "Hong"
};
person.likes = ["apple", "samsung"];
person.printHello = function(){
	return "hello";
}
  • 객체 속성의 값이 함수나 배열, 객체 리터럴일 때 값을 변경하거나 새로운 속성을 추가할 수 있다.

    이미 만들어진 객체에 나중에 속성을 추가하는 것을 자바스크립트에서는 "속성을 동적으로 추가한다."라고 한다.

객체 속성 동적으로 삭제하기

  • 객체 속성을 접근할 시 맨 앞에 delete 키워드를 명시하면 해당 속성을 삭제할 수 있다.
// 객체 속성 삭제 1
const person = {
	name = "Hong Gildong"
};
delete person.name; // 또는 delete person["name"]
console.log(person); // { } 출력

객체 데이터 관리 방법

  • 일반적으로 const 키워드로 선언한 상수 변수는 재할당이 불가능하다.
  • 하지만 const 키워드로 선언한 상수 변수에 객체에 속성을 추가하거나 삭제할 수 있다.
  • 왜냐면 객체 자료형의 특성인 참조 때문이다.

자바스크립트 자료형 종류

  • 기본 자료형
  • 참조 자료형

기본 자료형은 깊은 복사를 진행하고 참조 자료형은 얕은 복사를 진행한다.

기본 자료형

  • 깊은 복사란 ? 변수에 데이터를 할당할 때 데이터 그 자체를 할당하는 것을 의미한다.

// 깊은 복사 예시코드
let num = 10;
let copyNu = num;
num = 20; // 변수 num을 재할당
console.log(num); // 20
console.log(copyNum); // 10
// 변수 num만 값이 변경되고 변수 copyNum은 변경되지 않는다.
// 변수 copyNum은 변수 num의 값을 복사한 별도의 데이터를 가지고 있기 때문이다.

복사한 값을 재할당할 대 한쪽 데이터가 변경되어도 서로 영향을 미치지 않게 복사되는 것 = 깊은 복사 라고 한다.

참조 자료형

  • 참조 자료형은 변수 공간에 데이터가 할당되는 것이 아닌 데이터가 위치하고 있는 메모리의 주소 값만 할당되는 것을 의미한다.(="참조한다"라는 의미)
// const의 오류가 발생하는 원인 예시 코드
const person = {
  	name : "Hong Gildong"
};
person = {
 name : "Sucoding" 
}; 
//TypeError : Assignment to constant variable
  • 위에 코드가 에러가 발생하는 이유는 const는 재할당이 안되기 때문이다.
  • 하지만 다음 코드와 같이 변수에 할당된 객체에 속성을 추가하거나 값을 변경하는 건 가능하다.
// 객체 속성 변경 예제코드
const person = {
  name : "Hong Gildong"
};
person.name = "Hong";
  • person 입장에서 데이터를 재할당하는 것이 아니기 때문에 오류가 발생하지 않으며 변수에 할당된 객체의 주소 값은 그대로이며 주소 값이 참조하는 원본 객체 데이터만 변경되기 때문에 새로운 속성을 추가할 수 있다.
// 객체 복사 예제코드
const person = {
  name : "Hong Gildong"
};
const copyPerson = person; // 변수 person에 할당된 객체를 변수 copyPerson에 복사한다.
person.name = "Hong"; // 변수 person에 할당된 객체의 값을 변경한다.
console.log(person.name); // Hong
console.log(copyPerson.name); // Hong
  • 객체가 변수에 할당될 때 변수는 주소 값만 가지고 있어 복사할 때도 주소 값만 복사한다.
  • 두 변수는 같은 주소 값을 가지게 되며 바라보는 원본 데이터의 위치가 같다.
  • 변수 person의 데이터를 변경하면 변수 copyPerson의 데이터까지 변경된다.

한쪽 데이터가 변경되면 다른 쪽 데이터도 변경되어 서로 영향을 받는 것을 얕은 복사(shallow copy) 라고 한다.


자바스크립트의 객체 생성 방법

  • 자바스크립트의 객체 생성 방법에는 객체 리터럴, 생성자 함수, 클래스가 존재한다.

객체 리터럴

  • 가장 직관적인 방식을 사용한다.
  • { }를 사용해 객체를 만들고, property와 method를 정의한다.
// 객체 리터럴 예제코드
const person = {
  name: 'John Doe',
  age: 30,
  greet: function() {
    console.log('Hello, my name is ' + this.name + '!');
  }
};
person.greet(); // 출력: Hello, my name is John Doe!

생성자 함수

  • new 키워드를 사용한다.
  • 객체를 여러번 생성해야 할 때 유용하다.
function Person(name, age) {
  this.name = name;
  this.age = age;
  this.greet = function() {
    console.log('Hello, my name is ' + this.name + '!');
  };
}

const person1 = new Person('John Doe', 30);
const person2 = new Person('Jane Doe', 25);

person1.greet(); // 출력: Hello, my name is John Doe!
person2.greet(); // 출력: Hello, my name is Jane Doe!

클래스 사용

  • ES6+ 클래스 기반 문법을 사용한다.
  • class 키워드 사용 정의 이후 new 키워드로 생성한다.
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log('Hello, my name is ' + this.name + '!');
  }
}

const person = new Person('John Doe', 30);
person.greet(); // 출력: Hello, my name is John Doe!

리터럴 vs 생성자 vs 클래스 어느 것을 사용해야할까🧐

객체 리터럴생성자클래스(ES6+)
장점- 가장 간단하고 직관적이다.
- 단일 객체를 빠르게 생성 및 초기화가 가능하다.
- 유사 객체를 여러 개 생성할 수 있다.- 객체 지향 프로그래밍 지원을 한다.
- 클래스 상속이 간단하고 명확하다.
- 구조적이고 명확한 문법을 제공한다.
단점- 코드 중복의 가능성이 있다.
- 프로토타입 상속 설정이 어렵다.
- 문법적으로 복잡하고 구식일 수 있다.
- new 키워드 누락 시 버그가 발생할 가능성이 있다.
-이전 자바스크립트 버전에서 사용이 어렵다.
사용 시점단순한 구조의 단일 객체가 필요할 때 사용한다.- 유사한 객체를 여러 개 생성해야 할 때 사용한다.- 객체 지향 프로그래밍 활용 시
- 큰 규모의 프로젝트나 팀 작업시 사용한다.
  • 객체 사용에 있어 Class가 꼭 필요한 것은 아니다.
  • OOP적으로 코드를 작성할 때 Class를 사용한다. (독립된 영역을 구현한다)

Object 내에서 메서드 표현

  • Object(객체) 내부에서 사용하는 Function은 Method로 부른다.
  • Object의 property value이다.

리터럴 생성시 선언하기 (기본)

const myObject = {
  property: 'Value',
  myMethod: function() {
    console.log('This is a method.');
  }
};

myObject.myMethod(); // 출력: This is a method.

ES6 축약 메서드 표현법 (Shorten)

const myObject = {
  property: 'Value',
  myMethod() {
    console.log('This is a method using ES6 shorthand.');
  }
};

myObject.myMethod(); // 출력: This is a method using ES6 shorthand.

Function 동적 추가

const myObject = {
  property: 'Value',
};

myObject.anotherMethod = function() {
  console.log('This is another method.');
};

myObject.anotherMethod(); // 출력: This is another method.

getter/setter, Private 변수

  • 외부 스코프에서 내부 스코프의 변수에 접근하지 못하도록 한다.
  • 데이터의 안전한 관리를 목적으로 한다.
  • 잘못된 참조를 차단한다.
class Person {
  #name; // private 필드 선언한다.

  constructor(name) {
    this.#name = name;
  }

  // getter
  getName() {
    return this.#name;
  }

  // setter
  setName(name) {
    this.#name = name;
  }
}

const person = new Person('John');
person.name = 'Park' // private 변수를 직접 변경했을 경우 반영되지 않는다.
console.log(person.getName()); // John
person.setName('Jane');
console.log(person.getName()); // Jane

참고 문헌📜

  • 코딩 자율학습 HTML + CSS + 자바스크립트 - 김기수 지음-
profile
천천히, 꾸준히, 그리고 끝까지

0개의 댓글