블록체인 sw개발자

[JS](객체)프로토타입 & Class

sang969 2023. 7. 12. 13:56

 

 

객체의 선언과 호출

let 객체명 = {
   키명: 값,
   키명: 값,
 }

객체는 값을 표현할 때 [이름: 값]으로 쌍으로 이루어져 있다.

 

사람을 소개한다고 보도록 하겠습니다.

"안녕하세요! 홍길동이고요, 30살이고요, 남자이고, 서울 살아요 키는 183입니다."

=> let person = ['홍길동',  30,  '남자',  '서울', 183]; 이라고 하면 어쩌면 이해하기 어려울수가 있다.

 

더쉽게 정리하자면

let person = {
    name: '홍길동'
    나이: 30
    성별: '남자'
    주소: '서울'
    키: 183
}

※메서드(Method)란 : 객체가 갖고 있는 동작 혹은 객체에 주는 명령이다. JS로 말하자면 값이 함수인 유형이다.

 

ex) 객체 선언

데이터 처리

  • 변수는 데이터를 한개 저장하는 박스,
  • 배열은 데이터를 여러개 담는 기차와 같다,
  • 객체는 데이터를 표집합 처리.

 

객체 생성자

객체 생성자는 함수를 통해서 새로운 객체를 만들고 그 안에 넣고 싶은 값 혹은 함수들을 구현한다

 

생성자 함수 문법

function 생성자함수명(매변){
  this.속성 = 값;
}

let 변수명 = new 생성자함수명();

※new라는 키워드로 객체를 새로운 인스턴스로 생성한다. new = 키워드

 

ex)

function Mini(color, wheel, roof) {
  this.brand = 'Mini 3Door';
  this.oil = 12.3;
  this.door = 3;
  this.color = color
  //속성명 = 매개변수 옛날부터 같이 쓰는경우가 많았다.
  this.wheel = wheel;
  this.roof = roof;
  
  this.starting = function(x){
    if(x == 'on'){
      alert(this.color + '인'+ this.brand+'가 시동이 켜졌습니다.');
    }else if(x == 'off'){
      alert(this.color+ '인'+this.brand+'가 시동이 꺼졌습니다.');
    }
  }

  let gdCar = new Mini('Island blue', '16''white');
  let chCar = new Mini('Chili red', '18','white');
  
  gdCar.starting(''); //on, off
  chCar.starting(''); //on, off

 

같은 객체 생성자 함수를 사용하는 경우, 특정 함수 또는 값을 재사용 할 수 있는데 바로 프로토타입이다.

 

프로토타입(prototype)

프로토타입은 "유전자" 라는 뜻이다.(객체의 원형, 즉 객체의 부모가 가지는 유전자 , 상속받은 데이터, 메소드)

prototypeproperties(속성)를 통해 생성자 함수는 인스턴스에게 프로토타입 객체에 있는 데이터, 메소드를 상속한다.

(인스턴스는 사용 가능하다)

※Prototype은 '연결'이다.

  • 함수 객체만 가지고있다.
  • 생성자를 가지는 원형으로 가리킴
  • 함수(function)와 new 를 통해 클래스를 비스 무리하게 흉내낼 수 있습니다.
  • Prototype은 클래스,객체의 내용 복사 없이도 상속을 구현할 수 있게 해주는 방법이다.
  • 같은 속성과 메서드이기 때문에 메모리를 잡아먹지 않도록, 이를 해결하기 위해 나왔다.
function Person() {}

Person.prototype.eyes = 2;
Person.prtotype.nose = 1;

let gildong = new Person();
let sangH = new Person();

document.write(gildong.eyes); //2
...

Person.prototype 이라는 빈 Object가 어딘가에 존재하고, Person 함수로부터 생성된 객체(gildong, sangH)들은 어딘가에 존재하는 Object에 들어있는 값을 모두 갖다쓸 수 있습니다.

 

※동일한 생성자 함수로 생성된 객체들은 내부적으로 [__proto__] 라는 속성을 사용하여 생성자 함수에 존재하는 prototype이라는 속성을 참조하여 같은 공간을 공유하고 있습니다.


class

Javascript에서는 객체를 상속하기 위하여 프로토타입이라는 방식을 사용한다. 하지만

prototype 의 상속은 class의 상속과 다른 얘기입니다. 왜냐하면 javascript에는 클래스가 없기 때문이다.

  • class를 사용하는 가장 큰 이유는 재사용성이다. (완전체로 만들기 보다는 우리가 재조립을해서 원하는 기능을 만든다.)
  • class는 객체를 찍어내는 도장이다.

기본문법(class를 선언만 해준다면 class 객체를 바로 만들 수 있다.)

class Person{

}
let kim = new Person();

console.log(kim)

// Person {}

Class 초기값 설정해주기

 

Constructor(생성자)를 이용하면 class 객체의 초기 값을 설정해 줄 수 있다.

class 내부에서 Constructor는 한 개만 존재할 수 있으며, 2 번 이상 사용시 Syntax Error가 발생할 수 있다.

 

Constructor를 이용하여 Person 클래스에 초기 값을 설정해보도록 하자.

class Person{
  constructor (name, age, city) {
    console.log('constructor');
    this.name = name;
    this.age = age;
    this.city = city;  
  } 
}

let Park = new Person("Park", "30", seoul);

console.log(Park)

// Person { name: "Park", age:"30", city:"seoul"}

이처럼 Constructor는 새로운 클래스를 생성할 때 가장 처음 실행되면서 초기값을 설정해준다.

 

1. ex)

class Counter {
    count;
    name;
    #pricount;
    
    constructor(name) {
      this.count = 0;
      this.name = name;
      this.#pricount = 0;
    }
    increase() {
      console.log(this);
      this.count += 1;
    }
  }
  
const count = new Counter("클래스");
count.increase();
//count.increase(); 추가할때마다 1씩 증가한다.

 

console 값

2. ex)

class MyName {
  constructor(name, age, gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
  }
  getName() {
    return this.name;
  }
  getAge() {
    return this.age;
  }
  getGender() {
    return this.gender;
  }
}

const userName = new MyName("Park", 30, "M");
console.log(userName.getName());
console.log(userName.getAge());
console.log(userName.getGender());

class는 이런식으로 내부에서 생성자를 통해 객체가 만들어지고 해당 메서드나 프로퍼티에 객체를 통해 접근해서 사용하는 방식으로 사용된다. 클래스내에 정의한 메서드는 해당 클래스의 프로토타입으로 저장된다.

 

만약에 생성자 함수를 통해 정의한다면 아래와 같이 정의 될 수 있을 것이다.

const MyName = function (name, age, gender){
  this.name = name;
  this.age = age;
  this.gender = gender;
}
MyName.prototype.getName = function () {
 return this.name;
}
MyName.prototype.getAge = function () {
 return this.age;
}
MyName.prototype.getGender = function () {
 return this.gender;
}

const UserName = new MyName("Park", 30, "M");
console.log(UserName.getName());
console.log(UserName.getAge());
console.log(UserName.getGender());

Class를 이용한 상속

class를 이용하면  더 직관적이고 객체지향스럽게 상속을 구현할 수 있다.

 

 

오버라이딩

 

일반적인 객체지향 언어처럼 생성자 오버라이딩 혹은 메서드 오버라이딩을 할 수 있다.

class Mammal {
  constructor(name){
    this.name = name;
    this.feetNum = 4;
  }
  move() {
    console.log("움직인다.")
  }
  eat() {
    console.log("먹다")
  }
}

class Cat extends Mammal {
  attack() {
    console.log("공격한다")
  }
}

const cat1 = new Cat("짬타이거")

생성자 오버로딩 시에는 super를 호출해 상속받은 클래스의 속성을 가져온다.

 

마찬가지로 메서드 역시 super를 호출해서 상속받은 클래스의 메서드 기능을 가져올 수 있다. 만약에 메서드의 기능을 추가하는 경우라면 이런식으로 사용하면 된다. eat 메서드를 참고하자.

 

메서드 오버라이딩을 통해 아예 기능을 변경해버릴 수도 있다. super 없이 그냥 원하는 기능을 구현해주면 된다. move 메서드 처럼 말이다.