JavaScript의 객체에 대해 알아보자
객체
✔️ 객체는 중괄호 {}를 사용해서 생성하고, 중괄호 안에 이 객체에 필요로 하는 속성들을 정의함
이 속성들은 속성:속성값 형태로 정의함 ('키:밸류' 형태와 같음)
속성값으로는 모든 자료형의 값을 담을 수 있음 (문자열, 숫자, 논리값, 배열, 객체, 함수, ...)
[ 표현법 ]
var 변수명 = {
속성명 : 속성값,
속성명 : 속성값,
속성명 : 속성값,
...
};
*속성명이 키값, 속성값이 밸류값이 됨
해당 객체 내부의 각 속성에 접근하는 방법
👉🏻 객체명['속성명'] // 홑따옴표, 쌍따옴표 모두 가능
👉🏻 객체명.속성명
<button onclick="test1();">실행확인</button>
<div id="area1" class="area big"></div>
<script>
function test1() {
// 자바스크립트에서의 배열: 자바에서의 ArrayList
var arr = ["Dry Mango", 4000, "pickle", ["mango", "sugar"]];
// 자바스크립트에서의 객체: 자바에서의 HashMap
// 백엔드단에서 주고받을 때도 훨씬 편함!
var product = {
pName : "Dry Mango",
price : 4000,
kind : "pickle",
ingredient : ["mango", "sugar"]
};
//console.log(product);
//console.log(typeof(product));
var area1 = document.getElementById("area1");
area1.innerHTML = "product: " + product + "<br>";
// 요소 안에 객체를 출력하고자 객체명을 제시한 경우
// 기본적으로 [object Object]로 출력됨
// 해당 객체 내부의 각 속성에 접근하는 방법
// 방법 1. 대괄호를 이용하는 방법: 객체명["속성명"]
area1.innerHTML += "<b>방법1. 객체명['속성명'] 으로 접근하기 </b> <br>";
// '속성명', "속성명" 모두 가능하나 위에서는 쌍따옴표 안이기 때문에 홑따옴표로 지정!
area1.innerHTML += "product['pName']:" + product['pName'] + "<br>";
area1.innerHTML += "produet['price']: " + product['price'] + "<br>";
area1.innerHTML += "produet['kind']: " + product['kind'] + "<br>";
area1.innerHTML += "produet['ingredient']: " + product['ingredient'] /* .toString() */+ "<br>";
area1.innerHTML += "produet['ingredient'][0]: " + product['ingredient'][0] + "<br>";
area1.innerHTML += "<hr>";
// 방법 2. .을 이용하는 방법: 객체명.속성명
area1.innerHTML += "<b>방법 2. 객체명.속성명으로 접근하기 </b><br>";
area1.innerHTML += "product.pName : " + product.pName + "<br>";
area1.innerHTML += "product.price: " + product.price + "<br>";
area1.innerHTML += "product.kind : " + product.kind + "<br>";
area1.innerHTML += "product.ingredient: " + product.ingredient /* toString()*/ + "<br>";
area1.innerHTML += "produet.ingredient[0]: " + product.ingredient[0] + "<br>";
area1.innerHTML += "produet.ingredient[1]: " + product.ingredient[1] + "<br>";
}
</script>
객체 생성 특이케이스
(속성명 제시 시 반드시 문자열 형태로 제시해야 하는 케이스)
👉🏻 기존의 자바에서의 변수명이나 필드명을 지어 줄 경우 공백이나 특수문자 포함이 불가했음
자바스크립트에서의 객체의 속성명을 지어 줄 경우 공백이나 특수문자 포함이 가능함
단, 속성명 제시 시 공백이나 특수문자가 포함된 경우 반드시 "문자열"의 형태로 제시해야 함
공백이나 특수문자가 포함되어 문자열 형태로 속성명을 제시한 경우,
방법 1. 객체명.속성명 👉🏻객체 내 속성에 접근 불가
방법 2. 객체명["속성명"] 👉🏻 객체 내 속성에 접근 가능한 유일한 방법
<button onclick="test2();">실행확인</button>
<div id="area2" class="area small"></div>
<script>
function test2() {
var user = {
"user name" : "홍길동",
"age!!" : 20,
};
// console.log(user);
var area2 = document.getElementById("area2");
// .을 이용하여 속성값에 접근: 객체명.속성명
// area2.innerHTML = "user name: " + user."user name" + "<br>";
// area2.innerHTML = "age!! : " + user."age!!" + "<br>";
// => 이 경우 .을 이용하여 속성값에 접근 불가함!
// 대괄호를 이용하여 속성값에 접근: 객체명["속성명"]
area2.innerHTML = "user name: " + user["user name"] + "<br>";
area2.innerHTML += "age!!: " + user["age!!"] + "<br>";
}
</script>
객체에서의 반복문
👉🏻 객체가 가지고 있는 모든 속성들에 순차적으로 접근하고자 한다면 반복문을 사용 가능함
단, 단순 for loop 문으로는 불가능하고 for in 문만 사용 가능함
*자바에서의 foreach문 (향상된 for문)
for(자료형 변수명: 반복하고자하는배열명또는컬렉션명) {
해당 변수명에 매번 배열 또는 컬렉션에 들어 있는
0번 인덱스에서부터 마지막 인덱스에 들은 "값 자체"가 들어 있는 개념
}
* 자바스크립트에서의 for in문(foreach는 지원하지 않음)
for(var 변수명 in 배열명또는객체명) {
해당 변수명에 매번 배열 또는 객체에 들어 있는
배열일 경우: 0번 인덱스에서부터 마지막 "인덱스값"이 들어 있는 개념
객체일 경우: 첫 번째 속성명에서부터 마지막 "속성명"이 들어 있는 개념
=> 자바에서의 Map에서의 keySet() 와 비슷한 개념
}
<button onclick="test3();">실행확인</button>
<div id="area3" class="area small"></div>
<script>
function test3() {
var area3 = document.getElementById("area3");
// 자바스크립트에서의 배열
var arr = ["김갑생", 10, true];
for(var i in arr) { // i: 0, 1, 2 => 0번에서 마지막 인덱스 값 자체가 들어 있음
area3.innerHTML += i+ ": " + arr[i] + "<br>";
}
// in 뒤에 배열 제시 시
// 반복문을 돌 때마다 0에서부터 마지막 인덱스까지의 인덱스 수가 변수에 담김
// 자바스크립트에서의 객체
var game = {
title : "오버워치",
price : 35000,
language : "한국어 지원",
supportOS : ["windows32", "windows64"],
service : true
};
for(var key in game) { // key: "title", "price", "language", "supportOS", "service"
// . 을 통한 방법: 객체명.속성명
// => 진짜 game이라는 객체에 key라는 이름의 속성명을 찾음 (undefined)
// area3.innerHTML += key + ": " + game.key + "<br>";
// []을 통한 방법: 객체명["속성명"]
// => 객체에서 for in문을 사용할 경우 각 속성값에 접근하려면 반드시 대괄호를 이용한 방법을 써야 함!
area3.innerHTML += key + ": " + game[key] + "<br>";
}
// in 뒤에 객체 제시 시
// 반복문 돌 때마다 해당 객체의 속성명들이 앞쪽의 변수에 담김
}
</script>
객체의 메소드 속성
👉🏻 객체의 속성 중 함수 자료형인 속성을 메소드라고 부름
👉🏻 함수명(); => 함수
👉🏻 객체명.함수명(); => 메소드
👉🏻 this. : '내가 속한 객체로부터의'라는 뜻
<button onclick="test4();">실행확인</button>
<div id="area4" class="area small"></div>
<script>
function test4() {
var area4 = document.getElementById("area4");
var name = "김유저";
var dog = {
name : "포나",
kind : "닥스훈트",
eat: function(food) {
// area4.innerHTML = "eat 메소드가 호출되었습니다. <br>";
// area4.innerHTML = food; // 아래 입력한 내용물이 대입됨
// '닥스훈트 종류인 포나가 고구마를 먹고 있어요' 형태로 출력하고 싶다면?
// area4.innerHTML = kind + "종류인 " + name + "가 " + food + "를 먹고 있어요";
// 콘솔에 찍어 보니 kind is not defined가 나옴
// kind, name은 dog 안에는 있지만 food 함수 안에 정의된 변수가 아님!
area4.innerHTML = this.kind + " 종류인 " + name + "가 " + food + "를 먹고 있어요";
// 닥스훈트 종류인 김유저가 고구마를 먹고 있어요
area4.innerHTML = this.kind + " 종류인 " + this.name + "가 " + food + "를 먹고 있어요";
// 닥스훈트 종류인 포나가 고구마를 먹고 있어요
// 메소드 속성 내에 같은 객체 내의 속성명을 호출하고자 할 경우 this.을 붙여서 제시해 줘야 함
// 그렇지 않으면 지역변수를 우선적으로 찾게 됨! => 내가 원하지 않는 값을 찾을 확률이 높음
}
};
dog.eat("고구마");
}
</script>
*in 과 with 키워드
👉🏻 in: 객체 내에 해당 속성이 있는지 확인해 주는 키워드
"속성명" in 객체명: 해당 객체 내에 해당 속성이 존재할 경우 true 반환, 아니면 false 반환
👉🏻 with: 객체명을 매번 제시하는 것을 생략해 주는 키워드 (코드를 줄여 주는 키워드)
with(student) {
area5.innerHTML += "학생이름: " + /*student.*/name +"<br>";
area5.innerHTML += "국어점수: " + kor +"<br>";
area5.innerHTML += "수학점수: " + math +"<br>";
area5.innerHTML += "영어점수: " + eng +"<br>";
area5.innerHTML += "총점: " + getSum() +"<br>";
area5.innerHTML += "평균: " + getAvg() +"<br>";
// 모든 곳에 student.이 생략 가능해짐! 물론 써도 무방합니다
}
<기본 세팅 설정>
이름: <input type="text" id="name"> <br>
국어: <input type="number" id="kor"> <br>
수학: <input type="number" id="math"> <br>
영어: <input type="number" id="eng"> <br>
<button onclick="test5();">실행확인</button>
<div id="area5" class="area big"></div>
<script>
function test5() {
var name = document.getElementById("name").value; // "홍길동"
var kor = Number(document.getElementById("kor").value); // "80" -> 80
var math = Number(document.getElementById("math").value);
var eng = Number(document.getElementById("eng").value);
var student = {
name : name,
kor : kor,
math : math,
eng : eng,
toString : function() {
return this.name + " " + this.kor + " " + this.math + " " + this.eng;
},
getSum : function() {
return this.kor + this.math + this.eng;
},
getAvg : function() {
// return (this.kor + this.math + this.eng) / 3; // 이렇게 해도 되지만
return this.getSum() / 3;
}
};
var area5 = document.getElementById("area5");
area5.innerHTML = "student: " + student /* .toString() */ + "<br>";
// toString 속성을 추가하지 않았을 때: 'student: [object Object]' => 객체명만 쓰면 뒤에 .toString()이 함께 호출된 꼴이기 때문에
// toString 속성을 추가했을 때: 추가한 형식대로 나옴 'student: name입력값 kor입력값 math입력값 eng입력값'
area5.innerHTML += "sum: " + student.getSum() + "<br>";
area5.innerHTML += "avg: " + student.getAvg() + "<br>";
}
</script>
<in과 with의 적용>
// "속성명" in 객체명: 해당 객체 내에 해당 속성이 존재할 경우 true 반환, 아니면 false 반환
area5.innerHTML += "name이라는 속성이 있나: " + ("name" in student) + "<br>"; // true
area5.innerHTML += "sum이라는 속성이 있나: " + ("sum" in student) + "<br>"; // false, getSum은 있지만 sum은 없음
area5.innerHTML += "math라는 속성이 있나: " + ("math" in student) + "<br>"; // true // with(객체명) {~~~}: 해당 중괄호 내에 객체명이 중복된다면 생략 가능
/*
// with 키워드 사용 전
area5.innerHTML += "학생이름: " + student.name +"<br>";
area5.innerHTML += "국어점수: " + student.kor +"<br>";
area5.innerHTML += "수학점수: " + student.math +"<br>";
area5.innerHTML += "영어점수: " + student.eng +"<br>";
area5.innerHTML += "총점: " + student.getSum() +"<br>";
area5.innerHTML += "평균: " + student.getAvg() +"<br>";
*/
// with 키워드 사용 후
with(student) {
area5.innerHTML += "학생이름: " + /*student.*/name +"<br>";
area5.innerHTML += "국어점수: " + kor +"<br>";
area5.innerHTML += "수학점수: " + math +"<br>";
area5.innerHTML += "영어점수: " + eng +"<br>";
area5.innerHTML += "총점: " + getSum() +"<br>";
area5.innerHTML += "평균: " + getAvg() +"<br>";
// 모든 곳에 student.이 생략 가능해짐! 물론 써도 무방합니다
}
객체의 속성 추가 및 제거
속성 추가 👉🏻 객체명.속성명 = 값;
✔️ 중복된 키값 추가 불가하며 덮어씌워짐(자바에서의 Hashmap과 완전히 똑같음)
✔️ with 속성으로는 객체 속성 추가 불가함(대입 불가! 단지 속성값을 가지고 오는 용도로만 사용 가능)
속성 제거 👉🏻 delete(객체명.제거하고자하는속성명);
✔️ 제거된 속성은 undefined로 출력됨
<button onclick="test6();">실행확인</button>
<div id="area6" class="area small"></div>
<script>
function test6() {
// 테스트용 빈 object 객체 생성
var student = {};
// console.log(student); // 콘솔에 비어 있는 객체 생성 확인 완료!
// 비어 있는 객체에 속성 추가
// 객체명.속성명 = 값;
student.name = "홍길동";
student.hobby = ["게임", "음악감상"];
student.dream = "프로게이머";
student.age = 20;
// console.log(student);
// 객체 내에 중복된 키값을 추가
// => 중복된 속성 존재 불가, 덮어씌워짐을 볼 수 있음(Hashmap과 완전히 똑같음)
student.dream = "프로그래머";
// console.log(student);
// with 키워드의 경우에는 속성 추가가 되지 않음
// => with 키워드는 단지 속성값을 가져오는 용도로만 사용 가능
with(student) {
address = "서울시"; // 대입하는 용도는 불가!
}
// console.log(student);
var area6 = document.getElementById("area6");
area6.innerHTML = "student: " + student + "<br>";
// 메소드 속성 추가
student.toString = function() {
var str = "name: " + this.name + "<br>"
+ "hobby: " + this.hobby + "<br>"
+ "dream: " + this.dream + "<br>"
+ "age: " + this.age + "<br>";
return str;
}
area6.innerHTML += "student: " + student /* toString() */ + "<br>";
// 객체로부터 속성 제거
// delete(객체명.제거하고자하는속성명);
delete(student.hobby);
area6.innerHTML += "student: " + student + "<br>";
// 제거된 hobby 속성이 undefined로 출력됨
}
</script>