객체는 많은 속성을 가지고 있고, 그 속성들이 모두 데이터가 될 수 있다.
"추상화 (abstraction)" 는 프로그램에 필요한 요소만 사용해서 객체를 표현하는 것을 의미한다.
<script>
const students = [];
// 1. students 라는 빈 배열을 두고,
students.push({ 이름: "구름", 국어: 87, 영어: 98, 수학: 88, 과학: 90 });
students.push({ 이름: "별이", 국어: 92, 영어: 98, 수학: 96, 과학: 88 });
students.push({ 이름: "겨울", 국어: 76, 영어: 96, 수학: 94, 과학: 86 });
students.push({ 이름: "바다", 국어: 98, 영어: 52, 수학: 98, 과학: 92 });
// 2. 배열 안에 필요한 객체를 .push()를 이용해 추가한다.
console.log(JSON.stringify(students, null, 2));
// 3. 배열에 추가한 객체를 JSON 형식으로 콘솔에 표시
let output = "이름 \t 총점 \t 평균 \n";
// 4. ouput 이라는 변수에 이름, 총점, 평균에 각각 탭을 두고, 평균 이후에 줄바꿈을 추가한다.
for (const s of students) {
// 5. students 내부에 있는 요소 중 하나를 s라고 가정하고 반복문을 돌린다.
// 5-1. 반복문을 돌릴 시, 각 객체에 있는 속성을 전부 돌고 나서 다음 객체의 속성을 돌게된다.
const sum = s.국어 + s.과학 + s.수학 + s.영어;
// 6. sum 이라는 변수에 "."이라는 속성 접근자를 이용해서 각 속성별로 접근한 후 전체를 더한 값을 지정한다.
const average = sum / 4;
// 7. average 라는 변수에 sum을 4로 나눈 값을 할당한다.
output += `${s.이름} \t${sum}점 \t${average}점 \n`;
// 8. output에 객체의 이름 속성과 해당 속성들의 sum과 average를 추가 할당한다.
}
console.log(output);
// 9. 출력 시 각 학생의 이름과 해당 학생의 전체 과목 총 점과 평균을 구할 수 있다.
</script>
<script>
const students = [];
students.push({ 이름: "구름", 국어: 87, 영어: 98, 수학: 88, 과학: 90 });
students.push({ 이름: "별이", 국어: 92, 영어: 98, 수학: 96, 과학: 88 });
students.push({ 이름: "겨울", 국어: 76, 영어: 96, 수학: 94, 과학: 86 });
students.push({ 이름: "바다", 국어: 98, 영어: 52, 수학: 98, 과학: 92 });
console.log(JSON.stringify(students, null, 2));
const getSumOf = (students) => {
return students.국어 + students.영어 + students.수학 + students.과학;
};
// 1. students 배열에 있는 객체들의 모든 속성들을 접근하도록 "."를 사용해서 속성들의 합을 구하는 함수를 선언한다.
// 1-1. getSumOf 함수가 배열 students에 접근할 수 있도록 매개변수를 students로 한다.
const getAverageOf = (students) => {
return getSumOf(students) / 4;
};
// 2. getSumOf(students) 함수의 값을 4로 나눌 수 있는 함수 getAverageOf를 선언한다.
// 2-1. 이때 getAverageOf 함수도 students에 접근할 수 있도록 매개변수를 students로 준다.
let output = "이름 \t 총점 \t 평균 \n";
for (const s of students) {
output += `${s.이름} \t${getSumOf(s)}점 \t${getAverageOf(s)}점 \n`;
}
// 3. 반복문을 돌려 students 배열에 1개의 객체인 s에 접근한다.
// 3-1. 총합과 평균을 구하는 getSumOf와 getAverageOf 함수 사용 시, students가 아니라 s를 준다.
// 3-2. 출력 시 특정 객체의 속성값들의 합과 그 평균이 출력된다. (각 학생의 총점과 평균이 구해진다.)
console.log(output);
</script>
<script>
const students = [];
students.push({ 이름: "구름", 국어: 87, 영어: 98, 수학: 88, 과학: 90 });
students.push({ 이름: "별이", 국어: 92, 영어: 98, 수학: 96, 과학: 88 });
students.push({ 이름: "겨울", 국어: 76, 영어: 96, 수학: 94, 과학: 86 });
students.push({ 이름: "바다", 국어: 98, 영어: 52, 수학: 98, 과학: 92 });
console.log(JSON.stringify(students, null, 2));
for (const student of students) {
// 1. students라는 객체가 모여있는 배열에서 특정 객체에 접근할 수 있도록 반복문을 돌린다.
student.getSum = function () {
// 2. 각 객체에 접근하여 해당 객체의 속성으로 getSum이라는 함수를 부여한다.
return this.국어 + this.영어 + this.수학 + this.과학;
// 3. 해당 객체의 다른 속성을 지명하기 위해 this 키워드를 사용해서 해당 객체의 다른 속성을 더하는 내용을 리턴값으로 둔다.
};
student.getAverage = function () {
// 4. 그리고 반복문 내부에 다른 함수를 추가해서, 특정 객체에 getAverage라는 함수 속성으로 부여한다,
return this.getSum() / 4;
// 5. gerAverage 속성을 갖고있는 해당 객체를 this로 칭하고, 해당 객체의 다른 속성인 getSum에 접근하여 4로 나누고, 해당 값을 리턴한다.
};
}
let output = "이름 \t 총점 \t 평균 \n";
for (const s of students) {
// 6. students라는 객체가 모여진 배열에서 특정 객체 1개에 접근할 수 있는 반복문을 다시 돌린다.
output += `${s.이름} \t${s.getSum()}점 \t${s.getAverage()}점 \n`;
// 7. 특정 객체 접근 시, 해당 객체의 속성을 접근할 때 원하는 결과값을 출력할 수 있는 속성만 호출하여 결과를 출력한다.
}
console.log(output);
</script>
예시 ) 만약 students라는 배열이 1반 학생의 배열이고, 2반 학생의 배열에 똑같이 총합과 평균을 구하는 함수가 있다면, 함수 이름을 지정하는 것에 겹치지 않기 위해 신경써야 한다. 하지만 메소드를 추가할 경우 그런 문제가 사라지는 것.
<script>
function createStudent(이름, 국어, 영어, 수학, 과학) {
// 1. 객체를 생성하기 위해 함수를 선언한다.
return {
이름: 이름,
국어: 국어,
영어: 영어,
수학: 수학,
과학: 과학,
// 2. 함수가 리턴하는 값에 객체의 key를 부여하고, 함수의 매개변수를 key의 페어가 되는 값으로 설정한다.
getSum() {
return this.국어 + this.영어 + this.수학 + this.과학;
},
// 3. 함수에 또 다른 key-value로 메소드를 선언한다.
// 3-1. 해당 메소드의 값은 함수 createStudent 내부에 있는 또 다른 key-value를 this 키워드로 명시해서 원하는 값을 리턴할 수 있도록 설정한다.
getAverage() {
return this.getSum() / 4;
},
// 4. 평균을 구하는 함수도 선언한 후, 해당 함수 (key)가 리턴하는 값 (value)을 해당 함수 내 다른 속성임을 명시하기 위해 this 키워드를 사용한다.
// 4-1. this 키워드를 이용해서 명시한 후, 해당 속성(getSum())의 값을 4로 나누는 것이 getAverage라는 key의 value가 되는 것
toString() {
// 5. 마지막으로 원하는 결과값을 문자열로서 리턴할 수 있는 마지막 함수(동시에 객체의 key)를 선언한다.
return `${
this.이름
} \t ${this.getSum()} \t ${this.getAverage()}점 \n`;
// 6. 해당 함수가 리턴하는 값 또한 같은 객체 내의 다른 key의 속성이기 때문에 this 키워드를 이용한다.
// 6-1. 함수 toString()은 같은 객체 내 "이름"의 값과 "getSum()"의 값, "getAverage()"의 값을 문자열로 리턴한다.
},
};
}
// 7. 함수를 이용한 객체 생성 완료.
const students = [];
// 8. 빈 배열을 students라는 변수에 넣고,
students.push(createStudent("구름", 87, 98, 88, 90));
// 9. 빈 배열인 students에 함수를 이용해서 객체를 push한다.
// 9-1. 함수 createStudent()의 매개 변수로 넣은 값들이 key와 pair되는 value.
students.push(createStudent("별이", 92, 98, 96, 88));
students.push(createStudent("겨울", 76, 96, 96, 86));
students.push(createStudent("바다", 98, 52, 98, 92));
console.log(JSON.stringify(students, null, 2));
let output = "이름 \t 총점 \t 평균 \n";
for (const s of students) {
output += s.toString();
}
// 10. 반복문을 돌려서 students라는 배열 내부에 있는 각각의 객체 "s"에 접근하고,
// 10-1. output에 각 객체가 갖고 있는 값 중 하나인 toString()을 "."을 이용해서 접근하고 호출한다.
console.log(output);
</script>
getSum()
, getAverage()
, toString()
메소드를 생성하기 때문에 함수라는 기본 자료형보다 무거운 자료형이 여러 번 생성된다.클래스는 객체를 만드는 함수와 비슷한 것을 의미한다.
class 클래스 이름 ()
인스턴스는 클래스를 기반으로 만든 객체를 의미하지만, 보통 그냥 객체라고 부른다.
new 클래스 이름 ()
예시: 클래스 선언하고 인스턴스 생성하기
<script>
class Student {}
// 1. 클래스 선언
const student = new Student();
// 2. student라는 변수에 인스턴스를 할당한다.
const students = [
new Student(),
new Student(),
new Student(),
new Student(),
];
// 3. students라는 변수에 여러개의 인스턴트를 할당하기 위해 배열로 감쌌다.
</script>
생성자는 클래스를 기반으로 인스턴스를 생성할 때 처음 호출되는 메소드이다.
자바스크립트 함수는 재사용 가능한 코드를 묶음으로 사용하는 것 외에 객체를 생성 하기 위한 방법으로도 사용된다.
객체를 생성하기 위해서는 직접 객체를 반환해도 되지만, new 키워드를 사용하여 함수를 호출하게되면 return 문이 없어도 새로운 객체를 반환 시킨다.
생성자 함수는 new 키워드를 사용하지 않으면 일반적인 함수와 동일하게 동작하여 새로운 객체를 반환하지 않기 때문에 함수명을 대문자로 시작한다.
class 클래스 이름 {
constructor () {
//생성자 코드가 들어간다//
}
}
<script>
class Student {
constructor(이름, 국어, 영어, 수학, 과학) {
// 생성자 코드를 이용해서 유사 객체 생성
this.이름 = 이름;
this.국어 = 국어;
this.영어 = 영어;
this.수학 = 수학;
this.과학 = 과학;
}
}
const students = [];
students.push(new Student("구름", 87, 98, 88, 90));
// 호출 할 땐 New 키워드를 사용한다.
students.push(new Student("별이", 92, 98, 96, 88));
students.push(new Student("겨울", 76, 96, 94, 86));
students.push(new Student("바다", 98, 52, 98, 92));
</script>
function Teacher(name, age, subject) {
//Teacher 생성자 함수를 정의. 매개변수(parameter)를 name,age,subject를 정의하고 teach에 method 를 정의하였다.
this.name = name
this.age = age
this.subject = subject
this.teach = function (student) {
console.log(`${student}에게 ${this.subject}를 가르칩니다`)
}
// teach method 실행 시 콘솔에 글이 출력된다.
}
const jay = new Teacher("jay", 30, "javascript")
// new 키워드와 함께 생성자 함수를 호출 하여 생성자 함수 블록이 실행되어 return 없이도 새로운 객체가 반환되었음.
// 새로운 객체에서 this 가 가르키는 것이 jay 변수이다
console.log(jay)
// 출력 시 name: "jay", age:30, subject: "javascript"가 출력되고, teach는 함(function)으로 남아있는다.
jay.teach("fran")
// jay.teach(fran)으로 객체에 teach 메소드를 호출하면 "fran 에게 javascript를 가르칩니다" 라는 문구가 출력된다.
console.log(jay.constructor)
// 모든 객체에는 constructor 속성을 가진다.
// jay객체의 속성은 Teacher 의 속성을 가지고 있는것이 확인되었다.
// jay.constructor 를 하니 function teacher 가 나온것을 확인.
console.log(jay instanceof Teacher)
// instanceof 연산자를 이용하여 jay 객체가 Teacher 생성자 함수의 인스턴스 여부를 확인했더니 true가 출력된다.
const jay2 = Teacher("jay2", 32, "Java")
// new 키워드를 사용하지 않을 경우, 바로 Teacher라는 생성자 함수를 호출할 경우, 초기화가 진행되지 않아서 첫번째 인자로 받을 새 객체가 확인되지 않는다.
console.log(jay2)
// 출력 시 새로운 객체가 확인되지 않아 undefined가 출력된다.
console.log(age)
// 두번째 인자에 age는 할당이 되어 32가 출력된다.
// jay2의 자료형은 undefined다.
<script>
class Student {
constructor(이름, 국어, 영어, 수학, 과학) {
this.이름 = 이름;
this.국어 = 국어;
this.영어 = 영어;
this.수학 = 수학;
this.과학 = 과학;
}
getSum() {
return this.국어 + this.영어 + this.수학 + this.과학;
}
getAverage() {
return this.getSum() / 4;
}
toString() {
return `${
this.이름
} \t ${this.getSum()}점 \t ${this.getAverage()}점 \n`;
}
}
const students = [];
students.push(new Student("구름", 87, 98, 88, 90));
students.push(new Student("별이", 92, 98, 96, 88));
students.push(new Student("겨울", 76, 96, 94, 86));
students.push(new Student("바다", 98, 52, 98, 92));
let output = "이름 \t 총점 \t 평균 \n";
for (const s of students) {
output += s.toString();
}
console.log(output);
</script>
객체는 언제나 헷갈리는 개념인 것 같다...
자바스크립트가 돌아가는 구조에 대해서 잘 익히지 않으면 안되겠다.
출처: