class, prototype, 생성자함수

장돌뱅이 ·2022년 2월 24일
0

JavaScript

목록 보기
33/46

class

  • 오브젝트 생성
const ni = {
a: "consume",
b: "snowball"
}

const ku = {
a: "strike",
b: "courage"
}
  • class: 비슷한 오브젝트를 쉽게, 많이 만들고 싶을 때 (object 뽑는 기계처럼) 이용
  • 구 문법(생성자함수)
    여기서 this는 기계로부터 생성되는 object = instance
// 부모
function 기계(파라미터) {
  this.a = 파라미터;               
  this.b: "snowball"      		// 새로 생성되는 오브젝트에 b: "snowball" 추가하여 기본 속성값 넣어줌.
}

// 자식
const mkn = new 기계("consume")  // 오브젝트 생성
const are = new 기계("strike")   

다른 속성값 부여하고 싶을 때 함수 파라미터에 값을 넣어 생성

  • 신 문법(ES6)
    영어 대문자로 클래스명 작명
// 부모 Roler
class Roler {
 constructor(파라미터){
  this.a = 파라미터;             
  this.b: "snowball"
 }
}

// 자식 nus
const nus = new Roler()

자식에게 a, b 물려줌
부모-자식 상속관계를 다른식으로 구현할 수 있는 prototype이라는 문법이 있다.

prototype

prototype(오브젝트 자료)을 사용하여 자식 오브젝트에게 데이터를 물려줄 수 있다.

부모.prototype 를 개발자도구 콘솔에 입력해보면
부모는 자동으로 prototype라는 공간이 생긴다. prototype를 유전자(원형)라고 이해해보자

예를 들어서 prototype에 데이터를 추가하면 부모유전자에 데이터가 기록되므로 자식들이 사용가능하다.
그러나 자식을 출력하면 부모 유전자에 추가한 데이터가 자식에게 생성되지는 않는다.

결론적으로 자식이 어떤 속성을 물려받아 쓰고 싶을 때
1. 부모에게 기본 데이터를 넣어주어 자식이 그 속성을 직접 갖도록 하거나
2. prototype에 데이터를 추가할 수 있다.

// 부모
function 기계(파라미터) {
  this.a = 파라미터;               
  this.b: "snowball"      		// 자식이 {b:"snowball"} 가짐
}

기계.prototype.name = "lee"   // 데이터 추가, 부모만 {name: "lee"} 가짐


// 자식
const mkn = new 기계("consume")  // 오브젝트 생성
const are = new 기계("strike")   

오브젝트에서 데이터를 꺼낼 때
1. 직접 자료를 갖고 있다면 그것을 꺼내오고
2. 없으면 부모 유전자에게 물어봐서 꺼내온다.
3. 없으면 부모의 부모유전자까지 (prototype chain)
obj.name 에서 obj가 name을 갖고 있지 않으면 obj 부모 유전자에 name이 있냐고 물어본다.

예를 들어
const arr = [1, 4, 2]; 는 사람이 배열을 만드는 방식이고
const arr = new Array(1, 4, 2); 는 컴퓨터가 배열을 만드는 방식이다.
arr.sort()를 쓸 수 있는 이유는 Array라는 부모 유전자에 prototype이 sort()인 항목이 기록되어 있기 때문이다.

우리는 함수를 만들어 모든 배열 자료에서 쓸 수 있게 할 수도 있다.
Array.prototype.함수 = function(){}

클래스 상속

extends 키워드로 클래스를 상속한다.

// 클래스 (ES6에 추가된 스펙)
class Car {
  constructor(color) {
    // {} 클래스의 constructor는 빈객체를 만들어주고 this로 이 객체를 가리킨다.
    this.color = color;
    this.wheel = 4;
  }
  drive() {
    console.log("drive!!!");
  }
  stop() {
    console.log("stop!!!!");
  }
}

//car를 상속하는 자식 클래스 생성 
class Bmw extends Car {
  constructor(color) {
    super(color); // 생성자 오버라이딩
    this.navigation = 1;
  }
  stop() {
    super.stop(); // 부모 클래스에 정의된 메서드 사용: 오버라이딩 방식
    console.log("STOP");
  }
  park() {
    console.log("parking");
  }
}

const z4 = new Bmw("blue");

부모 생성자를 먼저 호출해야 한다. extends를 써서 만든 자식 클래스의 constructor는 빈객체가 만들어지는 작업과 this에 할당하는 작업을 생략하기 때문에 super()를 호출해야한다.
부모클래스의 프로퍼티를 이용하기 위해서는 constructor에 매개변수를 넘겨주어 부모생성자에 전달해주어야 한다.

생성자함수

생성자 함수명은 첫글자를 대문자로 쓴다.

function User(name, age){
  // this = {}
	this.name = name;
  	this.age = age;
  	this.sayName = function(){
      console.log(this.name)
    }
  // return this;
}

let user1 = new User("mike",30)
let user2 = new User("ari",20)
user2.sayName(); // 'ari'

생성자함수는 new를 붙여주어야 한다. 비슷한 객체를 여러개 만들 때 사용한다.
생성자함수가 새로운 객체를 만들어낼때 그 객체는 생성자의 인스턴스라고 부른다.

생성자함수와 클래스

// 생성자 함수
const User = function (name, age) {
  this.name = name;
  this.age = age;
  //this.showName = function () {  // 생성자함수는 객체 내부에 메서드가 있음
  //  console.log(this.name);
  //};
};

User.prototype.showName = function () {  // 메서드가 프로토타입에 저장된다. 
  console.log(this.name);
};

const mike = new User("Mike", 20);



// 클래스 (ES6에 추가된 스펙)
class User2 {
  // 클래스명 대문자로 시작
  constructor(name, age) {
    // constructor에 매개변수 지정, 객체 초기화
    this.name = name;
    this.age = age;
  }
  showName() {
    console.log(this.name); // 클래스 내에 정의한 메서드는 클래스의 프로토타입에 저장된다.
  }
}

const tom = new User2("tom", 20);

//for in 문에서의 차이 
for (const p in mike) {
    console.log(p)}
//name
//age
//showName

for (const p in tom) {
    console.log(p)}
//name
//age

생성자함수는 앞에 new 입력을 빼면 undefined로 에러가 안나지만
클래스는 new없이 호출하면 에러가 난다.

생성자함수로 만든 객체는 for in 문에서 프로토타입에 포함된 프로퍼티들을 다 보여주고 객체가 직접 갖고 있는 프로퍼티만 판별하기 위해서 hasOwnProperty를 사용한다.

클래스로 만든 객체의 메소드는 프로토타입에 저장되고 for in 문에서 제외된다.

0개의 댓글

관련 채용 정보