06_객체(object)

Onew·2025년 9월 26일
0

js

목록 보기
16/24
  • 목차

1. 객체

1_1) 객체(Object)란?

  • 키와 값의 쌍으로 이루어진 데이터 집합을 저장하는 자료형이다.
  • 데이터를 구조화하고 저장하는 데 사용하는 기본 단위이다.

1_2) 객체 생성 및 사용

  • 객체 리터럴(object-literal)을 사용한 객체 생성
    • 중괄호 {}를 사용해 객체를 생성하는 것이다.
    • 객체를 직접 정의하고 초기화 할 때 유용하다.
      const person = {
      		name : 'John',
      		age : 30,
      		city : 'New York'
      };
      ⇒ 위 코드에서 person이라는 객체는 name, age, city의 세 가지 속성을 가지고 있다.
    • 객체 리터럴을 이용해 객체를 생성할 때는 단일 인스턴스만 생성된다.
    • 코드의 가독성을 높이고 간편하게 객체를 정의할 수 있다.

2. 속성(property)

2_1) property 란?

  • 객체는 property의 집합이며 property는 key와 value로 구성 된다.
  • property key
    • property value에 접근하기 위한 식별자이다.
  • property value
    • JavaScript에서 사용할 수 있는 모든 값이다.
var student = {    
	// 프로퍼티 키는 name, 프로퍼티 값은 '유관순'    
	name : '유관순',    
	// 프로퍼티 키는 age, 프로퍼티 값은 16    
	age : 16,    
	// 프로퍼티 나열은 쉼표로 구분하며 마지막 프로퍼티 뒤에 쉼표를 사용해도 된다.
};

2_2) property 접근

  • 마침표 표기법(dot notation)
  • 대괄호 표기법(square bracket notation)
    • 프로퍼티 키는 반드시 따옴표로 감싼 문자열 사용한다.
    • 프로퍼티 키가 식별자 네이밍 규칙을 준수하지 않는 이름일 경우 반드시 대괄호 표기법 사용한다.
    • 프로퍼티 키가 숫자로 이뤄진 문자열인 경우 따옴표를 생략할 수 있다.
console.log(dog.name);    // 마침표 표기법(dot notation)
console.log(dog['name']); // 대괄호 표기법(square bracket notation)

2_3) property 변경/추가/삭제

  • 프로퍼티 변경
    • 이미 존재하는 프로퍼티에 값을 할당하면 프로퍼티 값이 갱신된다.
  • 프로퍼티 추가
    • 존재하지 않는 프로퍼티에 값을 할당하면 프로퍼티가 동적으로 생성 되어 추가되고 프로퍼티 값이 할당 된다.
  • 프로퍼티 삭제
    • delete 연산자는 객체의 프로퍼티를 삭제한다.
    • 만약 존재하지 않는 프로퍼티를 삭제하면 아무런 에러 없이 무시된다.
var dog = { name : '뽀삐' }
dog.name = '두부';          // 프로퍼티 값 갱신
dog.age = 3;                // 프로퍼티 값 추가
delete dog.age;             // 프로퍼티 삭제

3. 메서드(method)

3_1) method 란?

  • 객체 속성에 정의된 함수이다.
  • object.method() 방식으로 호출한다.
  • method는 객체를 행동할 수 있게 호출한다.
  • this
    • 생성자 함수 내부에서 this 키워드를 이용해 객체의 속성을 정의하고 초기화 한다.
    • new 연산자를 사용해 생성자 함수를 호출할 때, 새로운 객체가 생성되고 this는 이 새로운 객체를 가리킨다.
const person = {
    name: "홍길동",
    sayHello: function() {
        console.log("안녕하세요! 저는 " + this.name + "입니다");
    }
};

4. 객체 관련 문법

4_1) in operator

  • in 연산자
    • 속성이 객체에 존재 하는지 여부를 확인한다.
console.log('name' in person)  // true
console.log('country' in person)  // false

4_2) 순회

  • for in
    • for in 반복문을 이용해 객체의 모든 키를 순회할 수 있다.
var student = {
    name : '유관순',    
    age : 16
};
for (var key in student) {
    console.log(`${key} : ${student[key]}`);   // name : '유관순', age : 16 출력
}

4_3) shorthand

  • 프로퍼티 값 단축 구문
    • key name과 value 변수의 이름이 같은 경우 단축 구문을 사용할 수 있다.
  • 메서드 단축 구문
    • 메서드 선언 시 function 키워드 생략 가능

4_4) destructing assignment

  • 구조 분해 할당
    • 배열 또는 객체를 분해해 객체 속성을 변수에 쉽게 할당할 수 있는 문법이다.

      const person = {
          name: '김철수',
          age: 25,
          city: '서울'
      };
        
      const { name, age, city } = person;
      
      console.log(name, age, city); // '김철수' 25 '서울'
    • 함수의 매개변수로도 객체 구조 분해 할당 활용이 가능하다.

4_5) spread syntax

  • 전개 구문
    • 객체 복사 : 객체 내부에서의 객체 전개를 의미한다.

      const obj = {a: 1, b: 2, c: 3};
      const obj2 = {...obj, d: 4};
      
      console.log(obj2);  // {a: 1, b: 2, c: 3, d: 4}

4_6) optional chaining

  • 옵셔널 체이닝 연산자
    • obj?.prop 로 표기하며 사용한다.
    • 참조 대상이 null 혹은 undefined라면 에러 발생 대신 undefined를 반환한다.
    • Optional chaining 앞의 변수는 반드시 선언되어 있어야 한다
const person = {
    name: '홍길동',
    address: {
        city: '서울',
        country: '한국'
    }
}

console.log(person.address?.zipcode);

5. 객체 생성자 함수

5_1) 객체 생성자 함수란?

  • 객체 리터럴을 이용한 객체 생성 방식은 직관적이고 간편하지만, 단 하나의 객체만 생성한다.
    따라서, 동일 프로퍼티를 갖는 객체를 여러 개 생성해야 하는 경우 매번 같은 프로퍼티를 기술하기에 비효율적이다.
  • 객체를 생성하기 위한 템플릿처럼 생성자 함수를 사용하여 프로퍼티 구조가 동일한 객체 여러 개를 간편하게 생성할 수 있다.
function Student(name, age) {
  this.name = name;
  this.age = age;
  this.getInfo = function () {
    return `${this.name}(은)는 ${this.age}세입니다.`;
  };
}
const student = new Student("장보고", 30); // 인스턴스의 생성
console.log(student.getInfo());                 // 메서드 호출

5_2) 일반 함수와의 차이점

  • 일반 함수와 생성자 함수의 특별한 형식적 차이는 없다.
    (첫 문자를 대문자로 기술하여 구별하려 노력한다)
  • new 연산자와 함께 호출하면 생성자 함수로 동작하는 것이다.
    만약 new 연산자와 함께 호출하지 않으면 일반 함수로 동작한다.
  • 생성자 함수가 new 연산자 없이 호출 되는 것을 방지하기 위해 ES6에서는 new.target을 지원한다.
  • 대부분의 빌트인 생성자 함수(Object, String, Number, Boolean, Date, RegExp, …)는 new 연산자와 함께 호출 되었는지를 확인한 후 적절한 값을 반환한다.
    • String, Number, Boolean의 경우 new 연산자 없이 호출하면 객체 값이 아닌 문자열, 숫자, 불리언 값을 반환한다. 이를 통해 데이터 타입을 변환하는데 사용할 수 있다.

6. prototype

6_1) [[Prototype]]

  • 자바스크립트의 객체는 [[Prototype]]이라는 숨김 프로퍼티를 갖는다.
  • 이 프로퍼티 값은 null이거나 다른 객체에 대한 참조가 되는데, 다른 객체를 참조하는 경우 참조 대상을 프로토타입(prototype)이라 부른다.
  • object에서 프로퍼티를 읽으려 할 때 해당 프로퍼티가 없으면 자바스크립트는 자동으로 프로토타입에서 프로퍼티를 찾는다. ⇒ 프로토타입 기반의 상속
const user = {
  activate: true,
  login: function () {
    console.log("로그인 되었습니다.");
  },
};
const student = { passion: true };
student.__proto__ = user;
console.log(student.activate); // 프로퍼티 activate를 student에서도 사용 가능
student.login();                // 메소드 login도 student를 통해 호출 가능
console.log(student.passion);
  • ‘student의 프로토타입은 user이다.’ 혹은 ‘student는 user를 상속 받는다.’ 라고 한다.
  • 프로토타입에서 상속받은 프로퍼티를 상속 프로퍼티(inherited property)라고 한다.
  • proto 는 [[Prototype]]의 getter, setter이다.
    • 요즘에는 잘 사용하지 않지만 호환을 위해 남아있으며 직관적인 이해를 돕기 위해 여기서 사용한다.
    • Object.getPrototypeOf나 Object.setPrototypeOf을 써서 프로토타입에 접근하는 것이 좋다.
const greedyStudent = { class: 11, __proto__: student };
console.log(greedyStudent.activate); // user에서 상속
console.log(greedyStudent.passion);  // student에서 상속
  • 프로토타입 체이닝은 순환 참조(circle reference)가 허용되지 않는다.
  • proto 의 값은 객체 또는 null만 가능하며 다른 자료형은 무시된다.

6_2) prototype feature

const user = {
  id: "user",
  login: function () {
    console.log(`${this.id}님 로그인 되었습니다.`);
  },
};
const student = { __proto__: user };
student.id = "user01";
student.login(); // user01님 로그인 되었습니다.
  • 프로토타입은 프로퍼티를 읽을 때만 사용하며 프로퍼티를 추가, 수정, 삭제하는 연산은 객체에 직접 한다.
  • 메소드 내의 this는 프로토 타입에 영향받지 않으며 메소드를 객체에서 호출했든 프로토타입에서 호출했든 상관없이 this는 언제나 .앞에 있는 객체이다.
  • 메소드는 공유되지만 객체의 상태는 공유되지 않는다.
for (let prop in student) {
  console.log(prop);
  let isOwn = student.hasOwnProperty(prop);
  if (isOwn) {
    console.log(`객체 자신의 프로퍼티 ${prop}`);
  } else {
    console.log(`상속 프로퍼티 ${prop}`);
  }
}
  • for in 반복문은 상속 프로퍼티도 순회 대상에 포함시킨다.
  • hasOwnProperty : key에 대응하는 프로퍼티가 상속 프로퍼티가 아니고 obj에 직접 구현되어있는 프로퍼티일 때만 true를 반환한다.

6_3) constructor prototype

const user = {
  activate: true,
  login: function () {
    console.log("로그인 되었습니다.");
  },
};
function Student(name) {
  this.name = name;
} 
// 여기서의 prototype은 일반적인 프로퍼티
Student.prototype = user;// student.__proto__ == user
let student = new Student("홍길동");
console.log(student.activate);
  • new 연산자를 사용해 만든 객체는 생성자 함수의 프로토타입 정보를 사용해 [[Prototype]]을 설정한다.
  • F.prototype은 new F를 호출할 때만 사용된다.
    new F를 호출할 때 만들어지는 새로운 객체의 [[Prototype]]을 할당한다.
function Student() {} 
// 함수를 만들기만 해도 디폴트 프로퍼티인 prototype이 설정
// Student.prototype = { constructor: Student }

console.log(Student.prototype.constructor == Student);
let student = new Student();   // {constructor: Student}을 상속받음
console.log(student.constructor == Student); // true ([[Prototype]]을 거쳐 접근함)
  • 개발자가 특별히 할당하지 않더라도 모든 함수는 기본적으로 “prototype” 프로퍼티를 갖는다.
  • 디폴트 프로퍼티 “prototype”은 constructor 프로퍼티 하나만 있는 객체를 가리키는데, 여기서 constructor 프로퍼티는 함수 자신을 가리킨다.

0개의 댓글