[HTML | CSS | JavaScript | jQuery] 정리/JavaScript

JavaScript - 클래스, class

쎈코 2023. 5. 8. 01:21

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="css/example.css">
    <style>
    
    </style>
</head>
<body>
    <script>
        
        JavaScript > 클래스

        JavaScript > 틀 선언(O할 수도, X안 할 수도) > 객체 생성
        - Object() or 객체 리터럴

        1. Object() or 리터럴
        1-1. Object()
        const o1 = new Object();

        o1.name = '홍길동';
        o1.age = 20;

        o1.hello = function() {
            console.log(this.name);
            console.log(this.age);
        };

        o1.hello(); //홍길동, 20


        1-2. 리터럴 표기법
        const o2 = {
            name: '아무개',
            age: 20,
            hello: function() {
                console.log(this.name);
                console.log(this.age);
            }
        };

        o2.hello(); //아무개, 20


        1-3. 혼합
        const o3 = {
            name: '하하하'
        };

        o3.age = 20;    //o3에 추후 추가
        o3.hello = function() {
            console.log(this.name);
            console.log(this.age);
        };
        
        o3.hello(); //하하하, 20
        
        
        2. 생성자 함수
        - 파스칼 표기법(필수 X)
        - new 연산자와 같이 호출. 단독 호출 X
        function User() {
            this.name = '호호호';
            this.age = 25;
            this.hello = function() {
                 console.log(this.name);
                 console.log(this.age);
        };
    }
    
    User(); //단독 호출 > 전역 함수의 호출 > 내부에서의 this == window 객체
    
    const o4 = new User(); //이 때의 this는 앞에서 생성된(new) 객체를 가리킨다.
     => const o4 = {};와 같은 것
          o4.name = '호호호';
    
    o4.hello(); //호호호, 25
    
생성자 함수를 만드는 경우는 매개변수를 통해 이름, 나이 같은 것들을 만들때마다 서로 다른 User()를 만드는 이유로 만듦
    function Member(name, age) {
        this.name = name;
        this.age = age;
        this.hello = function() {
            console.log(this.name);
            console.log(this.age);
        };
    }

    const o5 = new Member('헤헤헤', 22);
    o5.hello(); //헤헤헤, 22


    3. ES6 > 클래스 추가
    class Mouse {
        생성자(고정-예약어)
        - 멤버 선언 + 멤버 초기화
        constructor() {
            this.name = 'G80';
            this.button = 3;
            this.price = 30000;
            // this.XXX : 변수를 선언하는 것과 같음
        }
    }

    //new라고 하는 키워드는 비어있는 객체를 만들어라
    //const m1 = {}; 와 같음
    const m1 = new Mouse(); 

    console.log(m1.name);   //G80
    console.log(m1.button); //3
    console.log(m1.price);   //30000


    
    // 잘 안 씀
    class Keyboard {
        //멤버변수(프로퍼티)
        name = 'K810';
        price = 120000;
        - 변수 선언 X. let name = 'K810'; 은 안됨
        - 변수 앞에 this가 생략되어있다고 보면 됨. this.name과 같은 것

        => 생성자 안에서 변수 선언 + 초기화 하는 거지 이 안에서는 선언 X > 딱히 메리트가 없음
    }

    const k1 = new Keyboard();
    console.log(k1.name);
    console.log(k1.price);



    메서드 프로퍼티
    class Item {

        constructor(name, color) {
            - 멤버변수 선언
            this.name = name;
            this.color = color; 
        }


        // function info() {
            // 클래스의 멤버 메서드를 만들때는 function 키워드를 쓸 수 없음 => 메소드(function 생략)
        info() {
            console.log(this.name, this.color);
        }
        //}

    const i1 = new Item('노트북', 'black');
    i1.info();  //노트북, black

    
    console.log(typeof i1); //object

 


    function test() {

    }

    console.log(typeof test()); //undefined. test()는 return값을 말하는 것 > test()에는 return값이 없으니 undefined
    console.log(typeof test)    //function

    - class 키워드를 사용한 클래스 == 생성자 함수의 다른 표현 방식
    console.log(typeof Item);   //class라고 나올것이라 예상하지만 > function이라고 뜸
    => JavaScript에는 클래스가 없음


    상속 가능
    class Monitor {

        constructor(name) {
            this.name = name;
        }

        info() {
            console.log('name: ' + this.name);
        }

    } //Monitor

    class LG100 extends Monitor {
        constructor() {
            super('LG100'); //super : 부모객체 참조해서 부모객체 생성자 만듦
        }

        //오버라이딩(재정의)도 가능
        check() {
            console.log('자체 메소드');
        }

        info() {
            super.info();    //부모 선호출
            this.check();    //자체 메소드. <- 내 스타일대로 재정의 가능
        }
    } //LG100

    const lg = new LG100();
    lg.info();  //name: LG100   -> 상속됨

 

    접근 지정자
    (관습) 멤버명 앞에 '_' or '$'가 있으면 비공개 멤버라는 의미!!
    > 통상적으로 이렇게 표시해놓으면 타 개발자들은 건드리지 않음
    class Computer {
        #c = 30;

        constructor() {
            - 멤버에 접근 지정자(public, private) X > 유사하게 흉내내는 개념은 있음
            this.a = 10;     //public
            this._b = 20;   //protected(=private) > 멤버명 앞에 언더바(_) 삽입. 사실 보이긴 하나, 외부에 공개 X (관습적으로)
            this.#c = 30;   //private > 멤버명 앞에 샵(#) 삽입. 찐 외부에 공개 X
        }
        test() {
            console.log(this.a, this._b, this.#c)
        }
    }

    const c1 = new Computer();
    console.log(c1.a);       //10. 접근 잘 됨  
    console.log(c1._b);     //20. 접근 잘 됨 > 접근 지정자가 없기 때문에 접근을 통제할 방법이 없음. 
    // console.log(c1.#c);   //에러. 진짜 private
    c1.test();
    // console.log(c1.ccc());



    getter, setter
    class Camera {
        constructor(name, price) {
            this._name = name;
            this._price = price;
        }

        setName(name) {
            this._name = name;
        }

        getName() {
            return this._name;
        }


        프로퍼티
        - set function() {}
        set price(price) {
            this._price = price;
        }
    
        - get function() {}
        get price() {
            return this._price;
        } => 프로퍼티 형태로 만드는게 더 편함
    
    }


    const c2 = new Camera('Cannon', 1000000);

    c2.setName('Sony');
    console.log(c2.getName());


    //c2.price(900000);
    //console.log(c2.price());

    프로퍼티
    - 내부적으로는 함수인데, 외부에는 변수처럼 사용하는 멤버 > set, get 프로퍼티
    c2.price = 900000;
    console.log(c2.price);  //900000

    
    </script>
</body>
</html>