자바스크립트 객체

자바스크립트의 객체와 배열은 원시타입이 아닌 참조타입이다.
객체가 아닌 문자,숫자,불리언 자료형은 원시타입이다.
자바스크립트에서 원시타입이 이닌 모든 데이터는 근본적으로 객체로 본다.
객체는 복합적인 정보는 프로퍼티 property(키와 밸류의 조합)으로 저장하는 자료형이다.

1. 객체 기본형식

const objName = {
  key1: value1,
  key2: value2,
  ...
};
// ⚠️ 블록이 아님!

📌 객체 선언 방식 1. 객체 생성자 new 사용

let person1 = new Object();

📌 객체 선언 방식 2. 객체 리터럴 방식 (더 선호함)

let person = {
  // key: "value", // 객체 프로퍼티
  name: "김도영",
  age: 28,
  marrige: false,
  say: function () {
    console.log(`안녕 나는 ${this["name"]}이고 ${person["age"]}살 입니다`);
  }
};

객체는 const로 생성할 수도 있음.
프로퍼티를 수정하는것과 상관없기 때문에 상수로 선언도 가능함.
함수가 아닌 프로퍼티: 멤버, 함수인 프로퍼티: 메서드 라고 부름.

1) 객체 프로퍼티 접근

속성값에 접근하는 두가지 방법

📌 접근법 1. 점 표기법 (많이 사용)

console.log(person.name);
console.log(person.age); 

console.log(
  person1.name,
  person1.age,
  person1.married
);

📌 접근법 2. 괄호 표기법

console.log(person["marrige"]);

console.log(
  person1['name'], // 속성명을 string으로
  person1['age'],
  person1['married'],
);

❗️존재하지 않는 키로 접근 시 undefined 반환

(키) in (객체) : 특정 키 포함 여부 확인

console.log(
  'age' in person1,
  'job' in person1
);

console.log(`name : ${"name" in person}`);
console.log(`gender : ${"gender" in person}`);

2) 프로퍼티 수정 및 추가, 삭제

객체 프로퍼티를 수정하거나 추가할 때 점표기법과 괄호 표기법을 사용할 수 있다.

// 특정 프로퍼티의 값 변경
person1.age = 26;
person1['married'] = true

// 새 프로퍼티 추가
person1.job = 'developer';
person1['bloodtype'] = 'B'

프로퍼티 삭제

delete person.age;
delete person['major'];
person.gender = null; // delete의 방식은 메모리가 남으므로 이 방식도 사용 가능

3) 식별자 명명 규칙에 벗어나는 키 이름 사용시

(1) 변수명 등으로 사용할 수 없는 이름의 키인 경우 : 대괄호 표기법만 사용가능

const obj = {
  1: '하나', // 숫자도 객체의 키로는 사용 가능
  'ab-cd': 'ABCD', // 문자 포함 시 키도 따옴표로 감싸야 함
  's p a c e': 'Space'
}

// 대괄호 프로퍼티 접근 연산자로만 가능
console.log(
  obj[1],
  obj['ab-cd'],
  obj['s p a c e']
);

// ⚠️ 오류 발생
// console.log(
//   obj.1,
//   obj.ab-cd,
//   obj.s p a c e
// );

(2) 표현식으로 키값 정의하기 : 대괄호 표기법만 사용

let idx = 0;
const  obj = {
  ['key-' + ++idx]: `value-${idx}`,
  ['key-' + ++idx]: `value-${idx}`,
  ['key-' + ++idx]: `value-${idx}`,
  [idx ** idx]: 'POWER'
}

console.log(obj);

📌 객체나 배열을 키값으로 사용시

const objKey = { x: 1, y: 2 };
const arrKey = [1, 2, 3];

const obj = {
  [objKey]: '객체를 키값으로',
  [arrKey]: '배열을 키값으로'
}

console.log(
  obj[objKey],
  obj[arrKey]
);

📌 매서드 method

객체에 축약표현으로 정의된 함수 프로퍼티를 매서드라고 함.
일반 함수 프로퍼티와 특성이 다름.

// 일반 함수 프로퍼티 정의
const person = {
  name: '홍길동',

  salutate: function (formal) {
    return formal
    ? `안녕하십니까, ${this.name}입니다.`
    : `안녕하세요, ${this.name}이에요.`;
  }
}
console.log(person.salutate(true));
// ⭐️ 메서드 정의
const person = {
  name: '홍길동',
  
  salutate (formal) {
    return formal
    ? `안녕하십니까, ${this.name}입니다.`
    : `안녕하세요, ${this.name}이에요.`;
  }
}
console.log(person.salutate(true));

2. 생성자 함수

1) 생성자 함수로 만들어진 객체

  • 생성자 함수명은 대문자로 시작
  • 생성자 함수로 만들어진 객체를 인스턴스 instance라고 부름.
  • this.~로 생성될 인스턴스의 프로퍼티를 정의
  • 생성자 함수는 new 연산자와 함께 사용
  • 생성자 함수에서는 매서드 정의 불가(객체 리터럴과 클래스에서는 가능)
// 생성자 함수 
function YalcoChicken (name, no) { 
  this.name = name;
  this.no = no;
  this.introduce = function () {
    return `안녕하세요, ${this.no}${this.name}점입니다!`;
  }
}

// 인스턴스 생성
const chain1 = new YalcoChicken('판교', 3);
const chain2 = new YalcoChicken('강남', 17);
const chain3 = new YalcoChicken('제주', 24);

console.log(chain1, chain1.introduce());
console.log(chain2, chain2.introduce());
console.log(chain3, chain3.introduce());

생성자 함수 앞에 new 연산자 사용함. new 연산자가 없으면 undefined를 반환함.

2) 프로토타입 prototype

프로토타입 prototype : 자바스크립트 객체지향의 중심

function YalcoChicken (name, no) {
  this.name = name;
  this.no = no;
  this.introduce = function () {
    return `안녕하세요, ${this.no}${this.name}점입니다!`;
  }
}

const chain1 = new YalcoChicken('판교', 3);
console.log(chain1);

// 본사에서 새 업무를 추가
// 프로토타입: 본사에서 배포하는 메뉴얼이라고 이해
YalcoChicken.prototype.introEng = function () {
  return `Welcome to Yalco Chicken at ${this.name}!`;
};

console.log(chain1.introEng());

해당 코드에서 introduce는 인스턴스, introEng는 프로토타입.

3) 타 방식으로 만든 객체와의 차이

객체 자체의 로그도 상세가 다름 유의 (앞에 생성자 함수명이 붙음)
instanceof : 객체가 특정 생성자 함수에 의해 만들어졌는지 여부 반환

function YalcoChicken (name, no) {
  this.name = name;
  this.no = no;
  this.introduce = function () {
    return `안녕하세요, ${this.no}${this.name}점입니다!`;
  }
}

function createYalcoChicken (name, no) {
  return {
    name, no,
    introduce () {
      return `안녕하세요, ${this.no}${this.name}점입니다!`;
    }
  }
}

// 객체 리터럴
const chain1 = {
  name: '판교', no: 3,
  introduce: function () {
    return `안녕하세요, ${this.no}${this.name}점입니다!`;
  }
};

// 객체 반환 함수
const chain2 = createYalcoChicken('강남', 17);

// 생성자 함수
const chain3 = new YalcoChicken('제주', 24);

3. 클래스 class

1) 클래스를 사용하여 인스턴스 만들기

클래스의 typeof는 함수이다.

class YalcoChicken {
  constructor (name, no) {
    this.name = name;
    this.no = no;
  }
  introduce () { // 💡 메서드
    return `안녕하세요, ${this.no}${this.name}점입니다!`;
  }
}

const chain1 = new YalcoChicken('판교', 3);
const chain2 = new YalcoChicken('강남', 17);
const chain3 = new YalcoChicken('제주', 24);

console.log(chain1, chain1.introduce());
console.log(chain2, chain2.introduce());
console.log(chain3, chain3.introduce());

클래스와 생성자 함수의 동작이 동일하지는 않음.

  • 차이점 1 : 클래스는 호이스팅 되지 않음.
  • 차이점 2 : 클래스는 new 없이 사용하면 오류.(생성자 함수는 undefined 반환함)
  • 차이점 3 : 클래스에는 엄격모드 적용됨.

2) constructor 매서드

  • 인스턴스 생성 시 인자를 받아 프로퍼티를 초기화함
  • 클래스 당 constructor 하나만 쓸 수 있음 (초과시 오류)
  • 다른 메서드 이름 사용 불가
  • 기본값 사용 가능
  • 필요없을 시 생략 가능 (인자가 없을 때 등)
  • 값을 반환하지 말 것. (생성자 함수처럼 암묵적으로 this 반환함)
class Person {
  constructor (name, age, married = false) {
    this.name = name;
    this.age = age;
    this.married = married;
  }
}

const person1 = new Person('박영희', 30, true);
const person2 = new Person('오동수', 18);
console.log(person1, person2);
// 인스턴스 초기화가 필요없는 클래스
class Empty {}
console.log(new Empty());

3) 클래스의 매서드

class Dog {
  bark () {
    return '멍멍';
  }
}
const badugi = new Dog();
console.log(badugi, badugi.bark());
profile
프론트엔드 개발자 첫걸음

0개의 댓글