
자바스크립트는 객체 기반 프로그래밍 언어이며, 원시 값을 제외한 나머지 모든 데이터를 객체(object)로 취급한다.
객체(object)란 간단히 이야기하자면 실생활에서 우리가 인식할 수 있는 사물과 같다.

클래스 기반 언어에서는 객체를 생성하기 위해 new 연산자를 사용한다.
하지만 프로토타입 기반 언어인 자바스크립트에서는 다양한 방법으로 객체를 생성할 수 있다.
- 객체 리터럴
- Object 생성자 함수
- 생성자 함수
- Object.create 메서드
- 클래스 (ECMA6 표준에서 추가)
참고: 프로토타입 + 생성자 / 클래스
객체는 코드블록 {} 안에 0개 이상의 property로 구성된 집합으로, 프로퍼티는 key와 value로 구성된다.
또한, 프로퍼티 값이 함수일 경우 일반 함수와 구분하기 위해 메서드(method)라고 부른다.
const x = {
key1 : 'value', //property1
key2 : 'value2', //property2
key3 : function(){
}, //method
}
객체의 성질을 모두 다 사용할 수 있기 때문이다.
배열과 함수 모두 속성들을 추가하거나 수정 및 제거할 수 있다.
function hello() {}
hello.a = 'really?'; // 새 속성 추가
const array = [];
array.b = 'wow'; // 새 속성 추가
console.log(hello.a); //really?
console.log(array.b); //wow!
다만, 함수와 배열은 주로 객체 리터럴과는 다른 목적으로 사용하기에 함수와 배열에 임의 속성을 넣는 경우는 드물다.
임의 속성을 넣고자 한다면 처음부터 객체 리터럴을 사용함.
리터럴은 사람이 이해할 수 있는 문자나 약속된 기호를 사용해 값을 생성하는 표기법을 말하는데, 자바스크립트에서 객체를 생성하는 가장 일반적인 방법이 객체 리터럴을 사용하는 것이다.
객체를 생성하기 위해 클래스를 정의하거나 new 연산자를 사용하지 않더라도 손쉽게 객체를 생성할 수 있다.
const object = {
property1_name: "property1_value",
property2_name: "property2_value",
property3_name: "property3_value", //
}
위의 형식과 같이 key : value 형식의 data를 직접 입력하는 방법이다.
key의 경우 따옴표가 필요 없으나, 예외적으로 property name 등 띄어쓰기를 할 경우에는 감싸주어야 한다.
아래와 같이, return 받을 값을 객체 리터럴로 경우를 나누어서 사용할 수 있다.
function createAccount(initialBalance) {
let balance = initialBalance;
return {
deposit: function (amount) {
if (balance + amount >= 0) {
balance += amount;
return `입금 성공! 현재 잔액: ${balance}`;
} else {
return '입금 실패! 잔액 부족';
}
},
getBalance: function () {
return balance;
}
};
}
각 프로퍼티는 쉼표( , )로 구분된다.
마지막 쉼표는 없어도 되지만 데이터 수정을 위해 붙이는 것을 추천한다.
✔ 프로퍼티 키(key) : 빈 문자열 포함 모든 string 또는 symbol 값
✔ 프로퍼티 값(value) : 자바스크립트에서 사용할 수 있는 모든 값
✔ 대괄호 표기법(bracket notation): 대괄호 프로퍼티 접근 연산자 ([ ])
const zerocho = { name: '조현영', date: 12, };
console.log(zerocho['name']); //'조현영'
이 때 쌍따옴표를 적지 않을 경우, 괄호 안에 변수가 적용되어 name은 'date'가 들어가게 된다. 즉, zerocho['date']와 같기 때문에 결과값은 12이다.
const name = 'date';
console.log(zerocho[name]);
✔ 마침표 표기법(dot notation) : 마침표 프로퍼티 접근 연산자 (.)
const zerocho = { name: '조현영', date: 12, };
console.log(zerocho.name); //'조현영'
console.log(zerocho.hello); // 존재하지 않는 속성에 접근 → 결과값 undefined
💡 온점을 사용할 수 없는 경우
속성 이름에 띄어쓰기가 들어있거나 온점이 들어있을 때, 숫자로 시작할 때는 변수['속성 이름'] 또는 변수['속성.이름']처럼 []를 사용해야만 속성에 접근 가능하다.
var.propertyName = propertyValue;을 하면 주어진 값으로 속성 값이 바뀜
zerocho.gender = 'F';
console.log(zerocho.gender);
F
var.NotExistPropertyName = value;을 하면 프로퍼티가 생성됨
zerocho.height = 180;
console.log(zercho.height);
180
delete var.propertyName;
delete zerocho.gender;
console.log(zerocho.gender);
undefined
let result = "name" in person;
존재하면 true 없다면 false를 반환
객체의 속성 값으로 함수가 들어갈 때 특별히 메서드(method) 라고 한다.
const debug = {
log: function(value) {
console.log(value);
},
};
debug.log('Hello, Method');
래퍼 객체란 이름처럼 원시 타입의 값을 감싸는 형태의 객체이다. number, string, boolean, symbol 의 데이터 타입이 객체가 아님에도 속성 접근자를 사용하여 객체처럼 메소드와 프로퍼티를 제공한다.
var str = "문자열"; // 문자열 생성
var len = str.length; // 문자열 프로퍼티인 length 사용
자바스크립트의 문자열은 원시 타입이지만, 문자열에 프로퍼티에 접근하려고 할 때 자바스크립트는 new String을 호출한 것처럼 문자열 값을 임시 객체로 생성한다.
이 객체를 래퍼 객체라고 하며, 이는 프로퍼티를 참조할 때 생성되어 참조가 끝나면 사라진다.
let name = "Tom";
//임시로 생성 : name = new String ("Tom");
document.write(name.length); //객체 메소드 length 호출, 메소드 처리
// name = new String ("Tom"); 소멸
// let name = "Tom"; 원시 타입만 존재
원시값 (객체가 아닌 값) 과의 차이점
객체(배열, 함수, 객체리터럴) 사이에 비교 연산 시에는 false 값이 반환된다.
객체가 아닌 값끼리는 true가 나온다. ( 문자열, boolean, null….)
객체는 모양이 같아도 생성할 때마다 새로운 객체가 생성된다.
따라서 객체끼리 비교를 하려면 기존 객체를 변수에 저장해두어야 한다.
const a = { name: 'zerocho' };
const array = [1, 2, a];
console.log(a === array[2]);
true
https://youtu.be/VXVIVblOBK4?t=190

💡 참조(reference)와 복사(copy)
const a = { name: 'zerocho' };
const b = a;
a.name = 'hero';
console.log(b.name);
hero

→ 변수 b에 a를 대입한 상황, 객체를 저장한 변수를 다른 변수에 대입하면 두 변수 모두 같은 객체를 저장하는 셈이 된다.
a와 b 변수 모두 같은 객체를 저장하고 있는 것이므로 객체의 속성 값을 바꾸면 변수 a와 b 모두 바뀐다. 이러한 상황일 때 변수 a와 b가 같은 객체를 참조하고 있다, 혹은 a와 b 그리고 객체 간에 참조 관계가 있다고 표현
let a = 'zerocho';
let b = a;
a = 'hero';
console.log(b);
zerocho

→ 반면, 원시값(객체가 아닌 값)일 경우 a를 바꿨는데도 b는 영향을 받지 않는다.
이렇게 참조가 생기지 않는 상황을 복사(copy)라고 한다.