📌 참고 사이트
객체
ko.javascript.info
📋 객체 (Object)
📍 원시형 (primitive type)
➡️ 앞선 시간에 배웠던 자료형으로 오직 하나의 값만을 저장하는 자료형이다.
➡️ 숫자, 문자열, 논리형, undefined, null, symbol 유형이 있다.
📍 객체
➡️ 원시형과 다르게 다양한 데이터(여러 개, 여러 자료형의 데이터)를 담을 수 있다.
➡️ 원시형을 제외한 자료형들은 모두 객체이다.
➡️ 아래에서 소개할 일반적인 객체 이외에도 Array(배열, 정렬된 데이터 컬렉션 저장을 위해 사용), Date(날짜와 시간 정보를 저장할 때 사용), Error(에러 정보를 저장할 때 사용) 등도 모두 배열이다.
📍 객체 만들기
➡️ 중괄호 { }를 이용해 만들고, 그 안에 '키(key): 값(value)' 쌍으로 구성된 프로퍼티를 원하는 만큼 넣을 수 있다.
➡️ 키(key)로는 문자형이나 심볼만 가능하고, 값(value)에는 모든 자료형이 가능하다.
(키로 숫자를 적으면 자동 형변환되어 type이 string인 숫자가 된다.)
객체를 만드는 방법에는 2가지가 있다.
1️⃣ 객체 생성자 문법
new 연산자를 이용해 객체 인스턴스를 생성한다.
let obj = new Object();
2️⃣ 객체 리터럴 문법
중괄호를 이용해 객체를 생성한다.
let user = {};
📋 리터럴과 프로퍼티
➡️ 객체 리터럴 문법을 이용해 객체를 작성해 보자.
let user = { // 객체명 user
name : "John", // key: "name" (string), value: "John" (string)
age: 30 // key: "age" (string), value: 30 (number)
};
위에서 작성한 user 객체에는 프로퍼티(키와 값 쌍)가 2개 존재한다.
➡️ 점 표기법을 이용해 프로퍼티 값을 읽고, 추가할 수 있다.
객체명.key명의 형식으로 작성한다.
(프로퍼티 값으로는 모든 자료형이 오는 것이 가능하다.)
점 표기법은 키가 공백이 없고, 숫자로 시작하지 않아야 하며, $와 _를 제외한 특수 문자로 이루어지지 않은 유효한 변수 식별자인 경우에만 사용이 가능하다.
// 프로퍼티 값 얻기
console.log(user.name); // John (user 객체에서 키 name과 쌍을 이루는 값인 John이 출력)
console.log(user.age); // 30 (user 객체에서 키 age와 쌍을 이루는 값인 30이 출력)
// 프로퍼티 추가
user.isAdmin = true; // user 객체에 키 isAdmin과 값 true (boolean)를 프로퍼티로 추가
console.log(user);
// {name: 'John', age: 30, isAdmin: true}
➡️ delete 연산자와 점 표기법을 사용해 프로퍼티를 삭제할 수 있다.
delete user.age; // user 객체에서 key가 age인 프로퍼티를 삭제한다.
console.log(user);
// {name: 'John', isAdmin: true}
➡️ 단어 여러 개를 조합하여 프로퍼티명(key 이름)을 만든 경우에는 프로퍼티 이름을 따옴표로 묶어주어야 한다.
또한 마지막 프로퍼티의 끝은 쉼표로 끝나는 것이 가능하다.
let user = {
name: "John",
age: 30,
"likes birds": true, // 주목!
};
❗ 상수(const)로 선언된 객체는 수정 가능하다!
const로 선언된 객체는 수정이 가능하다.
const user = {
name: "John"
};
user.name = "Pete"; // user 객체에서 키 name의 값을 Pete로 수정하기
console.log(user.name);
// {name: 'Pete'} (정상적으로 수정됨.)
위와 같이 const로 선언된 객체 안의 프로퍼티(내용)를 수정하거나 추가하는 것에서는 오류가 발생하지 않는다.
but 아래와 같이 const로 선언된 객체의 값 전체를 수정하려 할 경우 오류가 발생한다.
user = {
name: "Pete"
};
// Uncaught TypeError: Assignment to constant variable.
* 참고
[JavaScript] 불변 객체 만들기(const, Object.freeze()) — 거미줄코딩 (tistory.com)
[JavaScript] 불변 객체 만들기(const, Object.freeze())
개요 카카오 코딩테스트 문제를 풀다가 임의 객체 A를 배열B에 Push한 후 객체 A의 내용을 바꿨는데 배열B에 Push 되어 있던 객체 값이 바뀐 결과가 발생했다. 이 때 나는 배열에 push한 값은 value로
spiderwebcoding.tistory.com
📋 대괄호 표기법
➡️ 위에서 알아본 점 표기법은 여러 단어로 이루어진 키(user.likes birds와 같은 경우)나 숫자로 시작하는 키, 또는 $나 _를 제외한 특수문자가 존재하는 키에 접근하려 할 때 오류가 발생한다.
이렇게 키가 유효한 변수 식별자가 아닌 경우 '대괄호 표기법'의 방법을 사용할 수 있다.
(물론 키가 유효한 변수 식별자여도 사용 가능하다.)
➡️ 대괄호 표기법은 객체명[key]의 방식을 통해 프로퍼티의 값에 접근이 가능하다.
➡️ 대괄호 표기법의 경우 점 표기법에서와 다르게 대괄호 안에서 문자열을 사용할 경우 따옴표로 묶어주어야 한다.
let user = {};
// 프로퍼티 추가
user["like birds"] = true;
// 프로퍼티 값 읽기
console.log(user["like birds"]); // true
// 프로퍼티 삭제
delete user["like birds"];
➡️ 대괄호 표기법을 사용하면 변수로 프로퍼티 값에 접근하는 것이 가능하다. 따라서 사용자의 입력에 따라 접근해야 할 값이 달라질 경우 등을 고려하여 코드를 유연하게 작성이 가능하다.
but 점 표기법에서는 불가능하다.
let user = {
name: "John",
age: 30
};
let key = prompt("사용자의 어떤 정보를 얻고 싶으신가요?", "name");
// 변수로 프로퍼티 값에 접근해보기 (프롬프트 창에 "name"을 입력한 경우)
// 대괄호 표기법
console.log(user[key]); // John
// 점 표기법
console.log(user.key); // undefined
📍 계산된 프로퍼티
객체 생성 시 객체 리터럴 안에 key가 대괄호로 둘러싸여져 있는 경우 그것을 계산된 프로퍼티라고 한다.
대괄호 안에는 변수명이 들어간다.
즉, key 값이 무엇이 될지 모르는 상황에서 계산된 프로퍼티는 유용하게 쓰인다.
let fruit = prompt("어떤 과일을 구매하시겠습니까?", "apple");
let bag = {
[fruit]: 5, // 변수 fruit에서 프로퍼티 이름을 동적으로 받아온다.
};
console.log(bag.apple);
// 사용자가 프롬프트 창에 apple을 입력한 경우 5 정상적으로 출력
위 예시의 경우 [fruit]는 프로퍼티 이름을 변수 fruit에서 가져오겠다는 것을 의미한다.
[fruit] 자리에는 사용자가 프롬프트 창에 입력한 그대로가 들어간다.
이것은 앞서 본 대괄호 표기법으로 다음과 같이 나타낼 수 있다. but 계산된 프로퍼티 방법을 사용하는 것이 더 깔끔하다.
let fruit = prompt("어떤 과일을 구매하시겠습니까?", "apple");
let bag = {};
bag[fruit] = 5; // 대괄호 표기법을 사용해
console.log(bag[fruit]); // 5
대괄호 안에 계산식 같은 보다 복잡한 표현식을 넣는 것도 가능하다.
let fruit = "apple";
let bag = {
[fruit + "Computers"]: 5 // key 이름은 appleComputers가 된다.
}
💡 프로퍼티 이름이 확정되어 있고, 그것이 한 단어로 이루어진 단순한 이름이면 보통 점 표기법을 사용한다. 대괄호 표기법은 복잡한 상황이 발생했을 때 보통 사용한다.
📋 단축 프로퍼티
변수를 이용해 프로퍼티를 만들 때, key와 value값에 동일한 변수를 사용할 경우 '프로퍼티 값 단축 구문'을 사용하여 코드를 간결하게 작성하는 것이 가능하다.
let user = {
name, // name: name과 같다.
age: 30;
};
📋 프로퍼티명의 제약 사항
➡️ 이전에 변수 이름을 지을 때는 JS에서 사용하는 예약어(for, let, return 등)는 사용할 수 없다고 배웠다.
하지만 객체의 key에서는 이러한 제약이 없다. 즉, 객체의 key로 예약어를 사용하는 것이 가능한 것이다.
let obj = {
for: 1,
let: 2,
return: 3,
};
// 모두 정상적으로 작동
console.log(obj.for); // 1
console.log(obj.let); // 2
console.log(obj.return); // 3
➡️ 프로퍼티 이름으로 문자형이나 심볼형을 작성하지 않은 경우 문자형으로 자동 형 변환이 된다.
➡️ 프로퍼티 이름으로 __proto__를 사용하면 접근 시 할당한 값이 나오지 않고 객체가 나온다.
let obj = {};
obj.__proto__ = 5; // 숫자를 할당
console.log(obj.__proto__);
// {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
📋 프로퍼티 존재 여부 확인하기
📍 undefined로 특정 프로퍼티가 존재하는지 확인하기
➡️ JS에서는 다른 언어와 다르게 존재하지 않는 프로퍼티에 접근을 시도해도 에러를 뱉지 않고 undefined를 반환한다. 이를 이용해 특정 프로퍼티가 객체 내에 존재하는지를 확인할 수 있다.
let user = {};
console.log(user.noSuchProperty === undefined);
// true (noSuchProperty라는 프로퍼티가 user 객체에 존재하지 않는다.)
➡️ but 아래와 같이 프로퍼티 값으로 undefined를 할당한 경우 프로퍼티 존재 여부를 제대로 판별할 수 없다. 이럴 경우에는 아래에 제시된 in 연산자를 이용해 확인해야 한다.
let obj = {
test: undefined;
};
console.log(obj.test === undefined); // true (test의 값이 undefined이므로 일치해서 참, 결국 obj 객체에 test 프로퍼티는 존재하지 않는 것이 됨.)
console.log("test" in obj); // true (프로퍼티 유무를 제대로 확인 가능)
* undefined라는 값은 정의되어 있으나 값이 할당되지 않은 경우에 주로 사용하므로 프로퍼티 값으로는 잘 볼 수 없다. 값을 알 수 없거나 비어 있음을 나타내기 위해서는 주로 null이 사용된다.
📍 in 연산자로 특정 프로퍼티가 존재하는지 확인하기
➡️ 연산자 in을 사용해서도 프로퍼티 존재 여부를 확인할 수 있다.
in 옆에 프로퍼티명을 작성하여 확인한다. (보통은 문자열로 작성하고, 이때 따옴표를 꼭 작성해 주어야 한다.)
let user = {name: "John", age: 30};
console.log("age" in user); // true
console.log("name" in user); // true
📋 for ... in 반복문
📍 문법
for (let 변수명 in 객체명)의 형식으로 반복문을 작성하면 객체의 모든 키를 순회할 수 있다.
변수명 자리에는 꼭 key가 들어갈 필요는 없다. 그 자리에 반복 변수를 선언해야 한다는 점만 기억하자.
for (key in object) {
// 각 프로퍼티 키(key)를 이용하여 본문(body)을 실행한다.
}
<ex>
let user = {
name: "John",
age: 30,
isAdmin: true
};
for (let key in user) {
// 키 출력
console.log(key); // name, age, isAdmin
// 현재 key에 해당하는 값 출력
console.log(user[key]); // John, 30, true
}
📍 객체 정렬 방식
정수 프로퍼티는 오름차순으로 자동 정렬되고, 그 외의 프로퍼티는 객체에 추가한 순서 그대로 정렬된다.
<ex 1>
let codes = {
"49": "독일",
"41": "스위스",
"44": "영국",
//...
"1": "미국"
};
for (let code in codes) {
console.log(code); // 1, 41, 44, 49
}
위의 경우 key가 정수이기 때문에 오름차순으로 프로퍼티가 자동 정렬되었다.
작성한 순서 그대로 출력되지 않는다.
❓ 정수 프로퍼티
변형 없이 정수와 문자열을 왔다 갔다 할 수 있는 문자열을 말한다.
즉, 해당 문자열을 숫자로 변환하였을 때와 문자열일 때의 값이 같아야 한다.
ex) "49"는 정수 프로퍼티가 맞지만 "+49"나 "1.2"같은 경우 정수 프로퍼티가 될 수 없다.
위의 예시에서 작성한 순서대로 출력되게 하고 싶다면 key가 정수로 취급되지 않도록 각 나라 번호 앞에 '+'를 붙이는 트릭을 쓰면 된다.
그리고 key값 출력 시 숫자로 형변환이 가능한 단항 연산자 +를 사용하면 된다.
let codes = {
"+49": "독일",
"+41": "스위스",
"+44": "영국",
//...
"+1": "미국"
};
for (let code in codes) {
console.log(+code); // 49, 41, 44, 1
}
<ex 2>
let obj = {
name: "John",
surname: "Smith",
"2": "two",
"1": "one"
}
for (let key in obj) {
console.log(key); // 1, 2, name, surname
}
위와 같이 정수 프로퍼티와 일반적인 문자열 프로퍼티가 섞여 있을 경우 정수 프로퍼티가 오름차순으로 먼저 출력된 후 문자열 프로퍼티명이 작성한 순서대로 출력된다.
✏️ 과제
📍 객체야 안녕?
다음 각 동작을 한 줄씩, 코드로 작성해 보자.
1️⃣ 빈 객체 user을 만든다.
// 방법 1
let user = {};
// 방법 2
let user = new Object();
2️⃣ user에 키가 name, 값이 John인 프로퍼티를 추가해 보자.
// 방법 1
user.name = "John";
// 방법 2
user["name"] = "John";
3️⃣ user에 키가 surname, 값이 Smith인 프로퍼티를 추가해 보자.
// 방법 1
user.surname = "Smith";
// 방법 2
user["surname"] = "Smith";
4️⃣ name의 값을 Pete로 수정해 보자.
// 방법 1
user.name = "Pete";
// 방법 2
user["name"] = "Pete";
5️⃣ user에서 프로퍼티 name을 삭제해 보자.
// 방법 1
delete user.name;
// 방법 2
delete user["name"];
📍 객체가 비어있는지 확인하기
객체에 프로퍼티가 하나도 없는 경우 true, 그렇지 않은 경우 false를 반환해주는 함수 isEmpty(obj)를 만들어 보자.
function isEmpty(obj) {
// 만약 객체에 프로퍼티가 있다면 아래 반복문의 본문이 실행되어 false를 반환하고 함수가 종료된다.
for (let key in obj) {
return false;
}
// 객체에 프로퍼디가 없다면 반복문이 실행되지 않아 return true로 넘어온다.
return true;
}
let schedule = {};
console.log(isEmpty(schedule)); // true
schedule["8:30"] = "get up";
console.log(isEmpty(schedule)); // false
📍 변하지 않는 객체?
const와 함께 선언한 객체를 변경하는 게 가능할까?
const user = {
name: "John"
};
user.name = "Pete";
🅰️
가능하다.
변수 user에는 객체의 참조 값이 저장되어 있다. const는 그 값 자체가 변경되는 것을 막는 것이고, 객체의 내용인 프로퍼티를 변경하는 것을 막지는 않는다.
📍 프로퍼티 합계 구하기
모든 팀원의 월급에 대한 정보를 담고 있는 다음과 같은 객체가 있다.
let salaries = {
John: 100,
Ann: 160,
Pete: 130
}
모든 팀원의 월급을 합한 값을 구하고, 그 값을 변수 sum에 저장해주는 코드를 작성해 보자.
(위와 같이 객체가 구성되어 있을 경우 결과적으로 sum에는 390이 저장되어야 한다. but salaries 객체가 비어 있다면 sum에 0이 저장되어야 한다.)
🅰️
let sum = 0;
for (let key in salaries) {
sum += salaries[key];
}
console.log(sum);
📍 프로퍼티 값 2배로 부풀리기
객체 obj의 프로퍼티 값이 숫자인 경우 그 값을 2배 해주는 함수 multiplyNumeric(obj)을 만들어 보자.
multiplyNumeric 함수는 아무것도 반환하지 않아도 되고, 객체 자체를 수정해주기만 하면 된다.
🅰️
function multiplyNumeric(obj) {
for (key in obj) {
if (typeof obj[key] === 'number') {
obj[key] *= 2;
}
}
}
// 함수 호출 전
let menu = {
width: 200,
height: 300,
title: "My menu"
};
// 함수 호출하기
multiplyNumeric(menu);
// 함수 호출 후
console.log(menu);
// {width: 400, height: 600, title: 'My menu'}
'Javascript study' 카테고리의 다른 글
[JS] 메서드와 this (0) | 2023.08.16 |
---|---|
[Javascript] 참조에 의한 객체 복사 (0) | 2023.07.21 |
[Javascript] 함수 표현식 (0) | 2023.07.18 |
[Javascript] 함수 (0) | 2023.07.17 |
[Javascript] switch문 (0) | 2023.07.14 |
댓글