웹 프론트엔드

자바스크립트9 - 클래스 & 모듈

토리쟁이 2024. 1. 24. 02:35

이번 포스팅에서는 자바스크립트에서의 클래스에 대해 공부해 보려고 한다.


 

 

클래스와 객체

 

 

클래스(Class)

  • class 클래스명{constructor(){}}
  • ES6부터 등장한 객체(object)를 만드는 방법
  • 객체(object)를 만들 수 있는 틀(template)
  • 정해진 틀로 같은 규격의 객체를 여러 개 만들 수 있음 → 재사용 유리
  • new 키워드를 이용해 미리 만들어둔 클래스 형태의 객체를 만들 수 있음(instance화)
  • extends 키워드를 이용해 상속을 받을 수 있음
    • 상속시, 기존에 있던 클래스의 속성과 메소드를 받아와서 사용 가능
    • 상속시, 기존에 있던 클래스의 메소드를 가공하여 사용 가능
    • 오버로딩(Overloading): 상속받은 함수와 같은 함수명을 사용 but, 매개변수의 개수 or 타입을 다르게-
    • 오버라이딩(Overriding): 부모 클래스로부터 상속받은 메소드를 자식 클래스에서 재정의 / 같은 함수명, 매개 변수, 리턴 값이 모두 같아야 함

 

// class: object(객체)를 만들 수 있는 틀
/*
    속성
    - 만들어진 연도 year
    - 집의 이름 name
    - 창문의 개수 window
    메소드
    - 건물의 나이 출력 getAge()
    - 창문의 개수 출력 getWindow()
*/

class House{
    constructor(year, name, window){
        this.name = name;
        this.year = year;
        this.window = window;
    }

    // 메소드
    getAge(){
        console.log(`${this.name}은 건축한지 ${2024-this.year}년 됐어요`);
    }

    getWindow(){
        console.log(`${this.name}의 창문은 ${this.window}개 입니다.`);
    }
}

const house1 = new House(1789, 'old', 1);
house1.getAge(); // old은 건축한지 235년 됐어요
house1.getWindow(); // old의 창문은 1개 입니다.
console.log(house1.name); // old

// 상속
// extends 키워드를 사용해서 상속
// House 클래스의 속성과 함수 사용 가능
// House << Apartment 
class Apartment extends House{
    constructor(year, name, window, floor, windowMaker){
        super(year, name, window); // 상속받는 변수 명시
        this.floor = floor;
        this.windowMaker = windowMaker;
    }

    getAptInfo(){
        return `${this.year}년에 지어진 ${this.name}.
        총 층수는 ${this.floor}, 창문의 개수는 ${this.window}`;
    }

    // overriding 오버라이딩
    // 부모 클래스의 메소드를 이름은 똑같이 쓰되, 내용은 다르게 만들고 싶을 때
    // 메소드 재선언하여 덮어쓰는 것

    getWindow(){
        return `${this.name}의 창문은 ${this.windowMaker}에서 만들었고, ${this.window}개 입니다.`
    }

    // getAge() << 상속받아서 사용 가능
}

const ap1 = new Apartment(2022, 'raemian', 19, 50, 'KCC');
console.log(ap1.getWindow()); // raemian의 창문은 KCC에서 만들었고, 19개 입니다.
console.log(ap1.getAptInfo()); // 2022년에 지어진 raemian.
       // 총 층수는 50, 창문의 개수는 19
ap1.getAge(); // raemian은 건축한지 2년 됐어요
console.log(ap1);

 

 

 

 

 

모듈(Module)

  • 기능 단위로 모아둔 함수, 변수 등
  • 모듈명은 PascalCase를 사용할 것
  • /node_modules : Node.js의 모듈을 모아놓은 폴더
  • 모듈은 누구나 만들 수 있고, 다른 사람이 만든 모듈을 사용할 수도 있음
  • 주의) const { } 로 모듈을 가져올 때는 객체를 구조 분해해서 가져오기 떄문에 이름이 동일해야 함
  • 단, 하나만 내보낸 모듈은 이름이 달라져도 불러올 수 있음
  • ES2015(ES6) 모듈
    • 가장 최근에 출시된 자바스크립트 표준(2015)
    • 자바스크립트 자체 모듈 시스템 문법
    • 노트 모듈 시스템과  방식이 조금 다름
    • package.json에 "type":"module"을 추가하여 사용
    • export: 모듈 내보내기
      • 하단에서 export { };에 묶어서 한 번에 내보내기
      • 내보내고 싶은 것에 대해 각각 따로 export 키워드를 붙여서 내보내기
    • import ~ from ~ : 모듈 가져오기
    • export default: 하나의 큰 기능을 담당하는 function, class 등을 export 할 때 사용
      • 해당 파일에는 export 할 객체가 하나만 있음을 알려주는 키워드
      • export default로 내보내진 모듈을 import할 때에는 {}를 사용하지 x
  • common JS
    • 이전에 사용되던 자바스크립트 표준(~ES5)
    • exports: 모듈 내보내기
      • 하단에서 한 번에 modules.exports = {}; 로 묶어서 내보내기
      • 내보내고 싶은 것에 대해 각각 따로 exports.~ 키워드를 붙여서 내보내기
    • require: 모듈 가져오기

 

 

모듈에 대한 설명을 적었는데 제일 핵심 내용은 ES6에서는 모듈을 내보내고 불러오는 문법이 export & import 이고, common JS에서는 exports & require이라는 것이다.

 

 

 

common JS 방식에서의 모듈 내보내기 & 불러오기 예제를 살펴보자.

/*
    commonJS 방식
*/

const colors = ['#fff', '#ddd', 'red'];

const sayHi=()=>{
    console.log("hi");
};

// exports 키워드를 사용해서 한 번에 내보내기
// module.exports = {} 안에 넣으면 됨
module.exports = {
    colors,
    sayName
}


// exports 키워드를 사용해서 따로 따로 하나씩 내보내기
// 함수 선언문은 따로 exports 할 수 X -> 표현식 or 화살표 함수를 사용해서 exports 해야 함
// exports.~ 키워드 사용

exports.sayHi2 = () => {
  console.log("hi2");
};

exports.sayHi3 = function (name) {
  console.log(name);
};

 

위의 코드는 common JS 방식에서 변수, 함수를 한 번에 & 각각 내보내는 코드이다.

이렇게 내보낸 것들을 불러오는 코드는 다음과 같다.

/* common JS 방식*/
// 모듈 불러오기
// 가지고 오고 싶은 함수 or 변수만 구조 분해 할당을 이용해서 가져올 수 O

// 참고로, 03_exports1.js 파일은 common JS 방식에서의 모듈을 한 번에 내보내는 코드가 있다.

// 객체 구조 분해 형태로 가져오기
const {sayName} = require('./03_exports1'); 

// 한 번에 가져오기(객체로 불러옴)
const exports1 = require('./03_exports1');
exports1.sayName('hyhy'); // 점 표기법을 이용해 모듈에 들어있는 변수나 함수 등을 사용할 수 O


// 참고로, 03_exports2.js 파일은 common JS 방식에서의 모듈을 따로 따로 내보내는 코드가 있다.

// 따로 따로 가져오기
const {sayHi2, sayHi3} = require('./03_exports2');
sayHi2();
sayHi3('안녕하세요');

 

 

 

 

이제, ES6 방식에서의 모듈 내보내기 & 불러오기 예제를 살펴보자.

/* ES6 방식*/
// 모듈 한 번에 내보내기

const flowers = ['rose', 'sunflower', 'tulip'];

// flowers의 배열에서 원소를 추출하는 함수
function getFlower(idx){
    if(idx>=flowers.length || idx<0) return 'x'
    return flowers[idx];
}

// export 키워드를 사용해서 한 번에 내보내기
// exports {} 안에 넣으면 됨
export{flowers, getFlower};

// 별칭으로 내보낼 수도 있음
export{flowers as flr, getFlower as getFlr};


// export 키워드를 사용해서 따로 따로 하나씩 내보내기
export const animals = ['dog', 'cat'];

export function showAnimals(){
    animals.forEach((el)=>console.log(el));
}


// 큰 기능 하나만 내보내기
// export default 키워드 사용
// export에 비해 비교적 빠른 속도
export default function sayHi(){
    console.log('export default를 사용했습니다!');
}

 

 

ES6 방식을 사용할 때에는 반드시 package.json 파일에 "type":"module"을 작성해야 인식이 된다!

{
    "type":"module",
    "__comment__": "ES6 모듈로 진행할 때는 type:module 명시할 것"
}

 

 

위의 코드는 ES6  방식에서 변수, 함수를 한 번에 & 각각 내보내는 코드이다.

이렇게 내보낸 것들을 불러오는 코드는 다음과 같다.

 

/* ES6 방식*/
// 모듈 불러오기
// 참고로, 04_export1.js 와 04_export2.js 파일에는 ES6 방식의 모듈 내보내기 코드가 들어있다.
// import 키워드 사용

// 한 번에 모두 가져오기
import * as flowers from './04_export1.js';

// 점 표기법으로 꺼내서 사용
console.log(flowers.flr);
console.log(flowers.getFlr(1));


// 각각 따로 가져오기
import{showAnimals, animals} from './04_export2.js';
console.log(animals);
showAnimals();


// export default import 
// {} 필요없음 -> 어차피 하나만 불러오는거라서-
import sayHi from './05_exportdefault.js';
sayHi();