자바스크립트의 객체와 배열은 원시타입이 아닌 참조타입이다.
객체가 아닌 문자,숫자,불리언 자료형은 원시타입이다.
자바스크립트에서 원시타입이 이닌 모든 데이터는 근본적으로 객체로 본다.
객체는 복합적인 정보는 프로퍼티 property(키와 밸류의 조합)으로 저장하는 자료형이다.
const objName = {
key1: value1,
key2: value2,
...
};
// ⚠️ 블록이 아님!
let person1 = new Object();
let person = {
// key: "value", // 객체 프로퍼티
name: "김도영",
age: 28,
marrige: false,
say: function () {
console.log(`안녕 나는 ${this["name"]}이고 ${person["age"]}살 입니다`);
}
};
객체는 const로 생성할 수도 있음.
프로퍼티를 수정하는것과 상관없기 때문에 상수로 선언도 가능함.
함수가 아닌 프로퍼티: 멤버, 함수인 프로퍼티: 메서드 라고 부름.
속성값에 접근하는 두가지 방법
console.log(person.name);
console.log(person.age);
console.log(
person1.name,
person1.age,
person1.married
);
console.log(person["marrige"]);
console.log(
person1['name'], // 속성명을 string으로
person1['age'],
person1['married'],
);
console.log(
'age' in person1,
'job' in person1
);
console.log(`name : ${"name" in person}`);
console.log(`gender : ${"gender" in person}`);
객체 프로퍼티를 수정하거나 추가할 때 점표기법과 괄호 표기법을 사용할 수 있다.
// 특정 프로퍼티의 값 변경
person1.age = 26;
person1['married'] = true
// 새 프로퍼티 추가
person1.job = 'developer';
person1['bloodtype'] = 'B'
프로퍼티 삭제
delete person.age;
delete person['major'];
person.gender = null; // delete의 방식은 메모리가 남으므로 이 방식도 사용 가능
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
// );
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]
);
객체에 축약표현으로 정의된 함수 프로퍼티를 매서드라고 함.
일반 함수 프로퍼티와 특성이 다름.
// 일반 함수 프로퍼티 정의
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));
- 생성자 함수명은 대문자로 시작함
- 생성자 함수로 만들어진 객체를 인스턴스 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를 반환함.
프로토타입 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
는 프로토타입.
객체 자체의 로그도 상세가 다름 유의 (앞에 생성자 함수명이 붙음)
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);
클래스의 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 : 클래스에는 엄격모드 적용됨.
- 인스턴스 생성 시 인자를 받아 프로퍼티를 초기화함
- 클래스 당
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());
class Dog {
bark () {
return '멍멍';
}
}
const badugi = new Dog();
console.log(badugi, badugi.bark());