Class (클래스)
개념
ES5에서는 클래스가 없으며 객체형, 클로저, 생성자, 프로토타입 등을 이용해 클래스와 유사한 구조를 만들어 사용한다.
ES5와 다르게 ES6에서는 클래스 문법을 직접적으로 지원함.
내부적으로 Class는 격국 object형과 같다.
형식
<body>
<script>
class class_name {}
new class_name
</script>
</body>
선언과 인스턴스 생성
<body>
<script>
class CS
{
}
const a = new CS();
const aArray = [new CS(), new CS(), new CS()];
</script>
</body>
클래스의 생성자
constructor로 생성자를 호출한다.
ES6때 출현.
class cs {
constructor(){}
}
this를 통해 object에 변수를 등록한다. (object와 유사함.)
<body>
<script>
class student
{
constructor(_id = 0, _name = 0, _score = 0) //default parameter
{
this.id = _id;
this.name = _name;
this.score = _score;
}
};
const s1 = new student('JSR', '정상록', '100')
console.log(s1.id)
console.log(s1.name)
console.log(s1.score)
//JSR
//정상록
//100
</script>
</body>
* 생성자에 객체를 추가할 시 Shallow Copy(얕은 복사)에 주의한다.
<body>
<script>
class student
{
constructor(_id = 0, _name = 0, _score = 0)
{
this.id = _id;
this.name = _name;
this.score = _score;
}
};
const score = [100, 35, 88, 85]
const s1 = new student('JSR', '정상록', score);
console.log(s1.score);
score[0] = 50;
console.log(s1.score)
//(4) [100, 35, 88, 85]
//(4) [50, 35, 88, 85]
</script>
</body>
* Shallow copy(얕은 복사) 해결. (private 하단 참조)
<body>
<script>
class student
{
#id
#name
#score
constructor(_id = 0, _name = 0, _score = 0)
{
this.#id = _id;
this.#name = _name;
this.#score = [..._score];
}
getScore(){
return this.#score
}
};
const score = [100, 35, 88, 85]
const s1 = new student('JSR', '정상록',score);
console.log(s1.getScore());
//(4) [100, 35, 88, 85]
</script>
</body>
Method 추가
class의 method로 추가
- readability(가독성)이 좋다.
- 가장 기본적인 방법이다.
<body>
<script>
class student
{
constructor(_id = 0, _name = 0, _score = 0)
{
this.id = _id;
this.name = _name;
this.score = _score;
}
getId = function()
{
return this.id
}
};
const s1 = new student('220000', 'JSR', '정상록')
console.log(s1.getId())
//220000
</script>
</body>
Prototype을 사용한 Method 추가
- readability(가독성)이 떨어지는 치명적인 문제가 있다.
<body>
<script>
class student
{
constructor(_id = 0, _name = 0, _score = 0)
{
this.id = _id;
this.name = _name;
this.score = _score;
}
};
student.prototype.getId = function()
{
return this.id
}
const s1 = new student('220000', 'JSR', '정상록')
console.log(s1.getId())
//220000
</script>
</body>
인스턴스로 추가.
- readability(가독성)이 떨어지는 치명적인 문제가 있다.
<body>
<script>
class student
{
constructor(_id = 0, _name = 0, _score = 0)
{
this.id = _id;
this.name = _name;
this.score = _score;
}
};
student.prototype.getId = function()
{
return this.id
}
const s1 = new student('220000', 'JSR', '정상록')
s1.func = function()
{
console.log("Instance로 추가.")
}
</script>
</body>
문제
id, name, 3개의 score와 평균을 구하는 메서드를 가진 student 클래스를 구현하고자 한다.
각각의 장단점과 결론을 설명하시오.
- Object를 이용하여 구현하시오.
- constructor + prototype로 구현하시오.
- closure로 구현하시오.
- class로 구현하시오.
1. Object를 이용하여 구현하시오.
https://cruella-de-vil.tistory.com/38
[JavaScript] object type(객체형) +예제
객체형(Object type) 필요한 데이터와 기능을 가지고 있다. ▶ 개념 Primitive type을 제외한 데이터 타입의 베이스 인스턴스. JavaScript의 거의 모든 객체는 Object의 파생 인스턴스다. 데이터를 읽고 쓰는
cruella-de-vil.tistory.com
<body>
<script>
//object를 이용하여 만들기
const student1 = {
getAv : function() {
let av = 0;
for (let val of this.score)
{
av = av + val;
}
return (av/this.score.length).toFixed(2);
}
};
const student2 = {
id : 'JO',
name : '조온',
score : [80, 70, 98],
getAv : function() {
let av = 0;
for (let val of this.score)
{
av = av + val;
}
return (av/this.score.length);
}
};
const score = [100, 90, 80]
student1.id = 'JSR'
student1.name = '정상록'
student1.score = score
//출력
console.log(student1.id)
console.log(student1.name)
console.log(student1.score)
console.log(student1.getAv().toFixed(2))
//JSR
//정상록
//(3) [100, 90, 80]
//90.00
</script>
</body>
장점 :
- 직관적이다.
- 코딩하기 쉽다.
- Shallow copy와 상관없이 독립적으로 데이터를 유지한다.
단점 :
- 인스턴스 추가시 추가적인 코드가 발생한다.
- 코드의 중복이 일어난다.
- 코드의 일관성이 없어질 수 있는 여지가 존재한다.
- 접근제어 기능이 부재하다.
결론 :
- 인스턴스가 3개 이상이 되는 경우 object 방식은 좋지 않다.
- 함수의 수가 다수 존재할수록 복잡해진다.
- 정보가 단순할 경우 사용한다.
- Singleton 패턴에서 사용한다.
2. Constructor + Prototype을 이용하여 구현하시오.
https://cruella-de-vil.tistory.com/52
[JavaScript] 객체지향, Constructor(생성자), new
객체지향 자바스크립트 데이터, 함수 기반 프로그래밍 data가 보호받지 못하는 문제점이 있다. func2 입장에서 data1이 바뀐 이유에 대해서 알 수 없다. 객체지향 프로그래밍 기존의 데이터, 함수 기
cruella-de-vil.tistory.com
https://cruella-de-vil.tistory.com/54
[JavaScript] Prototype
Prototype 개념 prototype의 사전적 의미는 “원형"이다. 즉 “원래의 모양”을 뜻한다. 자바스크립트에서 사용하는 거의 모든 데이터는 기본적으로 “객체“(Object type)이다. 객체는 객체마다 기
cruella-de-vil.tistory.com
<body>
<script>
const student = function(_id, _name, _score)
{
this.id = _id;
this.name = _name;
this.score = [..._score] //spread
this.getTotal = function()
{
let total = 0;
for (let val of this.score)
{
total = total + val;
}
return total;
}
}
//prototype method 확장
student.prototype.getAverage = function()
{
let total = 0;
for (let val of this.score)
{
total = total + val;
}
return (total/this.score.length);
}
const score = [100, 87, 54]
const s1 = new student('JSR', '정상록', score)
const s2 = new student('JJ', '조조', [90, 70, 88])
//출력
console.log(s1.score)
console.log(s1.name)
console.log(s1.id)
console.log(s1.getAverage().toFixed(2))
//(3) [100, 87, 54]
//정상록
//JSR
//80.33
</script>
</body>
장점 :
- 객체의 생성부와 정의부가 분리된다. (중복제거, 가독성 증가...)
- 코드의 중복이 없다.
단점 :
- 메서드나 속성의 위치가 애매하다.
- this가 맥락에 따라 달라진다.
- 접근제어 기능이 부재하다. (No private) / 해결 : closure
결론 :
- 생성자로 사용할 시 method를 prototype으로 확장하지 않아도 된다.
3. closure로 구현하시오.
https://cruella-de-vil.tistory.com/53
[JavaScript] Closure(클로저) 예제
들어가기 앞서 Closure의 이해 https://cruella-de-vil.tistory.com/47 [JavaScript] Scope(스코프), Closure(클로저), var Scope (스코프) 개념 변수가 유효성을 가지는 범위. 스코프는 기본적으로 프로세스 메..
cruella-de-vil.tistory.com
<body>
<script>
//closure
const makeStudent = function (_id, _name, _score)
{
//Deep Copy 처리.
//L Val = R Val(우선처리)
_score = [..._score];
//기능 구현의 일관성이 떨어진다.
return {
getId() {
return _id;
},
setId(id) {
_id = id;
},
getName() {
return _name;
},
setName(name) {
_name = name;
},
getScore() {
return _score;
},
setScore(score, idx) {
_score[idx] = score;
},
getAverage() {
let total = 0;
for (let val of _score)
{
total = total + val;
}
return (total/_score.length);
}
}
}
const score = [90, 87, 77];
const st1 = makeStudent('JSR', '정상록',score)
console.log(st1.getScore())
console.log(st1.getId())
console.log(st1.getAverage().toFixed(1))
st1.setScore(100, 1)
console.log(st1.getScore())
console.log(st1.getAverage().toFixed(1))
//(3) [90, 87, 77]
//JSR
//84.7
//(3) [90, 100, 77]
//89.0
</script>
</body>
장점 :
- 접근 제어가 가능하다.
- 객체의 선언부와 정의부가 분리된다.
- 코드의 중복이 없다.
단점 :
- 문법적으로 어렵다. (내부 메커니즘 중 scope chain을 오용.)
- 기능 구현의 일관성이 없다.
결론 : ES5가 가지는 object, constructor, prototype, closure는 문제점과 한계가 존재한다.
4. Class를 이용하여 구현하시오.
<body>
<script>
//class를 이용하여 만들기
class student
{
constructor(_id = 0, _name = 0, _score = 0)
{
this.id = _id;
this.name = _name;
this.score = [..._score];
}
//id
getId() {
return this.id;
}
setId(_id) {
this.id = _id;
}
//name
getName() {
return this.name;
}
setName(_name) {
this.name = _name;
}
//score
getScore() {
return this.score;
}
setScore(score ,idx) {
this.score[idx] = score
}
//평균
getAverage() {
let total = 0;
for (let val of this.score)
{
total = total + val;
}
return total/this.score.length;
}
};
const score = [100, 87, 54]
const st1 = new student('JSR', '정상록', score)
//출력
st1.setId('SSS');
st1.setScore(0, 1);
console.log(st1.getId())
console.log(st1.getName())
console.log(st1.getScore())
console.log(st1.getAverage().toFixed(1))
//SSS
//정상록
//(3) [100, 0, 54]
//51.3
</script>
</body>
장점 :
- 접근제어가 용이하다.
- 객체의 선언부와 정의부가 분리된다.
- 다른 언어 객체지향 언어(ex) java)에서 사용하는 구현 스킬을 그대로 사용한다.
- 가독성이 좋다.
단점 :
- 현재로서 단점은 해결이 불가능하다.
결론 : Class는 ES5의 단점을 개선시켰다.
접근제어
private
클래스의 속성이나 메서드를 외부에서 접근할 수 없도록 하는 한정자.
#을 붙여 전방선언 한 뒤 모든 속성에 #을 붙임
이는 변수 명자체가 변경됨을 의미한다. EX) id → #id
<body>
<script>
class cs {
//private 선언
#a;
#b;
constructor(_a, _b) {
this.#a = _a;
this.#b = _b;
}
getA(){
return this.#a
}
getB(){
return this.#b
}
getAdd(){
return this.#a + this.#b
}
}
const result = new cs(10, 9)
console.log(result.getA())
console.log(result.getB())
console.log(result.getAdd())
//10
//9
//19
</script>
</body>
get, set
getter, setter를 위해서 만든 새로운 문법
형식
<body>
<script>
class cs {
#a;
#b;
constructor(_a, _b) {
this.#a = _a;
this.#b = _b;
}
get attribute_name () {
return value;
}
set attribute_name (value) {
}
}
</script>
</body>
예시
<body>
<script>
class cs {
#a;
#b;
constructor(_a, _b) {
this.#a = _a;
this.#b = _b;
}
//get 사용
get Add(){
return this.#a + this.#b
}
get A (){
return this.#a
}
//set 사용
set setA(_a) {
this.#a = _a;
}
}
const result = new cs(10, 9)
result.setA = 7; //set 사용
console.log(result.Add) //get사용
console.log(result.A)
//16
//7
</script>
</body>
'JavaScript' 카테고리의 다른 글
[JavaScript] 상속(Inheritance), super() (0) | 2022.04.21 |
---|---|
[JavaScript] throw(예외 발생) (0) | 2022.04.21 |
[JavaScript] Constructor 예제 (2) | 2022.04.19 |
[JavaScript] new.target (0) | 2022.04.19 |
[JavaScript] Prototype (0) | 2022.04.19 |