[JavaScript] 객체
객체
- 다른 자료형은 오직 하나의 데이터만 담을 수 있는 원시형(primitive type)이지만 객체는 다양한 데이터를 담을 수 있다.
객체 선언 및 호출
- 객체는 프로퍼티(키-값 쌍)를 저장하며 키 값을 사용하여 속성을 식별한다.
- 키는 문자열이며 속성에는 모든 자료형이 올 수 있다.
- 객체 생성자 또는 중괄호 {} 를 사용하여 객체를 생성한다.
function test1() {
//객체 생성자 호출
let obj = new Object();
//객체 리터럴 선언
let obj2 = {};
let product = {
//키-값 쌍으로 구성된 프로퍼티
pName : 'Dry Mango',
origin : 'Phillipines',
price : 10000,
ingredient : ['mango', 'sugar']
};
console.log('객체명.속성명으로 접근');
console.log(product.pName);
console.log(product.origin);
console.log(product.price);
console.log(product.ingredient);
console.log(product.ingredient[0]);
console.log(product.ingredient[1]);
객체명['속성명'] 입력할 때 single quotation이 잘 손에 안 붙는다.. 위의 표현식이 나에겐 더 맞음
console.log("객체명['속성명']으로 접근");
console.log(product['pName']);
console.log(product['origin']);
console.log(product['price']);
console.log(product['ingredient']);
console.log(product['ingredient'][0]);
console.log(product['ingredient'][1]);
객체의 키 식별자 테스트
- 객체의 키는 모든 문자열을 사용할 수 있다.
- 단, 식별자로 사용할 수 없는 단어를 키로 사용하거나 변수를 키로 사용하는 경우 무조건 대괄호를 사용해야 객체의 요소에 접근할 수 있다.
- 객체명.속성명 접근 불가
function test2(){
let objTest = {
'hello world' : 'Hello World!!',
'!@#$%^&*()' : 1234567890,
test : true
};
//변수에 담긴 key값
let key = "test";
console.log("=== objTest ===");
console.log(objTest);
console.log("객체명.속성명 접근 불가");
//console.log(objTest.'hello world');
// console.log(objTest.'!@#$%^&*()');
console.log(objTest.key);
console.log(objTest.test);
}
test2();
객체명.속성명 접근 불가 부분에서 console.log(objTest.test); 는 true로 잘 출력됐다.
- 객체명['속성명']으로 접근 가능
console.log("객체명['속성명']으로 접근 가능");
console.log(objTest['hello world']);
console.log(objTest['!@#$%^&*()']);
console.log(objTest[key]);
상수 객체는 수정 가능
- 상수 배열/객체의 속성은 변경 가능하나 상수 배열/객체를 다시 할당할 수는 없다.
function test3() {
const student = {name : '김땡땡', age : 20};
console.log(student);
- 해당 객체에서 속성 값 변경은 가능하다
- 새로운 객체 재할당은 불가능하다
student = {name : '김땡땡', age : 40};
객체의 속성 추가와 제거
- 처음으로 객체 생성한 이후 속성을 추가하거나 제거하는 것을 동적으로 속성을 추가한다 혹은 제거한다 라고 한다.
- 빈 객체 생성
let student = {};
console.log(student);
- 객체에 속성 추가
student.name = '주땡땡';
student.hobby = '게임';
student.strength = '프로그래밍';
student.dream = '개발자';
console.log(student);
- 객체 속성 제거(취미인 게임 제거)
delete(student.hobby);
console.log(student);
함수 활용한 객체 생성
function makeStudent(name, score){
let student = {
name : name,
score : score
};
return student;
}
- 위 코드 단축 프로퍼티
function makeStudent(name, score){
return{
name,
score
};
}
in 키워드
- 객체 내부에 해당 속성이 있는지 확인하는 키워드
function test5(){
let student = {
name : '주땡땡',
kor : 100,
eng : 80,
math : 90,
test : undefined
};
console.log('name' in student);
console.log('kor' in student);
console.log('eng' in student);
console.log('math' in student);
console.log('sum' in student);
console.log('test' in student);
- 값이 undefined인 속성인 in 연산자로 확인하는 것이 정확한다.
(값이 없는 sum과 test와 동일한 undefined 출력)
console.log(student.name);
console.log(student.sum);
console.log(student.test);
객체와 반복문
- 객체의 속성을 살펴볼 때에는 단순 for문으로는 사용 불가능하고 for in문을 사용해야 한다.
function test6() {
let game = {
title : 'DIABLO 3',
price : 35000,
language : '한국어지원',
supportOS : 'windows 32/64',
service : true
};
console.log(game);
console.log("=== 반복문 동작 ===");
for(let key in game){
console.log(key + " : " + game[key]);
}
}
test6();
객체의 메소드 속성
- 객체의 속성에 저장 된 함수를 메소드라고 하며 객체명.메소드() 와 같은 형식으로 사용된다.
- 메소드는 this로 객체를 참조한다.
function test7(){
let name = "뽀삐";
let dog = {name : "쪼꼬"};
//함수 표현식으로 함수를 만들고 객체 속성 dog.eat에 할당
//=> 메소드로 등록한다
dog.eat = function(food){
console.log(name + "가 " + food + "를 먹고 있네요.");
//객체 내에서 자신의 속성을 호출할 때는 반드시 this사용
console.log(this.name + "가 " + food + "를 먹고 있네요.");
};
//메소드 호출
dog.eat("고구마");
//선언된 함수 메소드로 등록
dog.walk = walk;
//메소드 호출
dog.walk("테헤란로");
}
function walk (place) {
console.log(this.name + "가 " + place + "를 산책하고 있네요.");
}
test7();
let human = {
name : '주땡땡',
eat(food){
console.log(this.name + "이 " + food + "를 먹고 있어요.");
//this를 사용하지 않고 외부 변수를 참조해서 객체에 접근
//가능하기는 하지만 변수명이 변경되는 상황 등이 있을 수 있으므로
//항상 this로 참조하자
//console.log(human.name + "이 " + food + "를 먹고 있어요.");
}
}
human.eat("짬뽕");
//외부 변수 참조시 발생할 수 있는 문제
let person = human;
human = null;
person.eat("샐러드");
생성자 함수
- 유사한 객체를 여러 개 만들어야 할 때 생성자 함수를 사용한다.
- 생성자 함수와 일반 함수는 기술적으로 다르지 않지만 함수 이름의 첫 글자는 대문자로 시작하고 new 연산자를 붙여 실행한다는 규칙이 있다.
function test8() {
// 생성자 함수 호출하여 객체 생성
let student1 = new Student("주땡땡", 100, 90, 80, 70, 60);
console.log(student1);
console.log("student 점수 합계 : " + student1.getSum());
console.log("student 점수 평균 : " + student1.getAvg());
let student2 = new Student(prompt("이름입력"),
Number(prompt('java 점수 입력')),
Number(prompt('oracle 점수 입력')),
Number(prompt('html 점수 입력')),
Number(prompt('css 점수 입력')),
Number(prompt('javascript 점수 입력')));
console.log(student2);
console.log("student2 점수 합계 : " + student2.getSum());
console.log("student2 점수 평균 : " + student2.getAvg());
//배열 선언
let students = [];
//배열에 객체 담기
students.push(student1, student2);
//객체 배열 출력
console.log(students);
}
test8();
find와 findIndex
- 객체 배열을 대상으로 특정 조건이 부합하는 객체를 배열 내에서 검색할 수 있다.
- 배열 요소를 대상으로 함수가 순차적으로 호출 된다.
- let 변수 = 배열.find/findIndex(function(item, index, array) {
// true가 반환 되면 반복이 멈추고 해당 요소를 반환/해당 요소의 인덱스 반환
// 조건에 해당하는 요소가 없으면 undefined를 반환});
function test9() {
let students = [ new Student("수지", 100, 90, 95, 85, 80),
new Student("제니", 70, 80, 90, 75, 60),
new Student("유아", 80, 65, 55, 90, 90)];
//제니라는 이름을 가진 학생 찾기
let jennie = students.find(item => item.name == '제니');
console.log(jennie);
//영미라는 이름을 가진 학생 찾기
let youngmi = students.find(item => item.name == '영미');
console.log(youngmi);
}
test9();
값이 없으면 undefined 출력
//java점수가 90점 이상인 학생의 인덱스 찾기
let java = students.findIndex(item => item.java >= 90);
console.log(java);
//oracle점수가 60점 미만인 학생의 인덱스 찾기
let oracle = students.findIndex(item => item.oracle < 60);
console.log(oracle);
java점수가 90점 넘는 학생이 0번째 인덱스 / oracle점수가 60점 미만 학생이 없으니 -1 출력
//평균 점수가 70점대 이상인 학생 인덱스 찾기
let avg70 = students.findIndex(item => item.getAvg() >= 70 && item.getAvg() < 80);
console.log(avg70);
1번, 2번 인덱스가 조건에 맞는데 1번인덱스만 출력이 됐다.
여러 값을 구할 때는 find나 findIndex로는 맞지 않다. 밑에서 filter로 출력해보자.
filter
- find/findIndex는 처음 true가 반환 된 하나의 요소만 반환 가능하므로 조건을 충족시키는 요소가 여러 개라면 filter 메소드를 사용한다.
- 문법은 유사하지만 조건에 맞는 요소 전체를 담은 배열을 반환한다.
let avg70 = students.filter(item => item.getAvg() >= 70 && item.getAvg() < 80);
console.log(avg70);