JS 5주차 정리 :: DOM | 클래스 | getters setters 개념 | 클래스 상속 | 클로저

728x90
반응형

1. DOM 소개

- JS 생긴 이유 : 브라우저에서 사용하기 위한 언어

- 사용자 = 브라우저 = 클라이언트 

- 브라우저는 렌더링엔진(번역)을 갖고 있음 --> 코드를 해석함

- 렌더트리를 구성함

- 이 파일을 브라우저에게 제공 > 브라우저는 렌더링해서 페인팅해줌 > 돔 트리가 생성됨 (계층)

<body>
  <nav> 메뉴가 들어감 
	<ul> 순서 없는 태그 안에 
    	<li> 첫번째 메뉴 (리스트 태그)
        <li> 두번째 메뉴

  <main>
	<h1> 글자
	<img src="" alt="이미지가 안뜨면 출력 문자열"> 이미지

  <footer>
	copyright.
</body>

 

2. DOM _API 실습

- DOM : JS가 HTML 문서를 해석하고 파싱한 결과물 / 브라우저에 기본적으로 내장된 API임

-  API : 메뉴판 같은 것. 다른 시스템에서 제공하는 기능을 사용할 수 있도록 도와주는 중간자 역할

- DOM은 브라우저 환경 (여기서 돌아감: DOM이 브라우저에 내장되어 있어 접근 & 제어 가능)

- 모든 DOM의 NODE =  속성 + 메서드

 

(1) node : html을 구성하는 모든 

//document.getElementById("demo"). innerHTML

(2) 속성 : innerHTML

(3) 메서드 : (동사형태) getElementById("demo")

 

- DOM요소에 접근 & 제어 (API때문에 가능함)

//노드 접근 
//1.querySeletor
document.querySeletor("#id명"); //ul태그에 접근 가능
document.querySeletor("#id명").children[0]; //ul태그의 자식요소들 확인 가능
document.querySeletor('태그명'); //footer 쓰면 footer 전체 영역 가져옴
document.querySeletor('footer').setAttribute("style","background-color : red;"); //배경 빨간색

//2.getElementBy~
document.getElementsByTagName("li"); // li여러개인것 추출
document.getElementsByTagName("li")[0]; // li여러개 중에 첫번째
document.getElementById("test");

//노드 제어
//1.createElement('태그명')
const newDiv = document.createElement('div');
document.body.append(newDiv); //추가

//2.innerText
document.querySeletor("#id명").children[0].innerText = '변경할 내용';

 

3. 클래스 소개 및 간단 예제

- 클래스 : 명세를 적어 놓은 설계도  / 인스턴스 : 실제 책상 

//클래스 (설계도)
class Person {
    //constructor () {} //생성자 함수
    //name, age
    constructor(name, age) {
        this.name = name; //this = 인스턴스(실체)
        this.age = age;
    }

    //메서드 형태의 동사 표현
    sayHello() {
        console.log(this.name + 'hello');
        console.log(`${this.name} hello`);
    }

    //메서드 형태의 동사 표현
    printMyAge() {
        console.log(`${this.name}의 나이는 ${this.age}살 입니다.`);
    }
}

//설계도를 통해 인스턴스(실제사물) 만들기
const person1 = new Person('홍', 20);
const person2 = new Person('박', 23);

person1.sayHello(); //person1 생성될때 메서드도 같이 생성됨
person1.printMyAge();

 

4. 클래스 생성 연습

class Car {
    constructor(modelName, modelYear, type, price) {
        this.modelName = modelName;
        this.modelYear = modelYear;
        this.type = type;
        this.price = price;
    }
    makeNoise() {
        console.log(`${this.modelName} 빵`);
    }
}

const car1 = new Car('자동차1', '2023', 'A', 300);
const car2 = new Car('자동차2', '2022', 'B', 100);
const car3 = new Car('자동차3', '2021', 'C', 500);

car1.makeNoise();
car2.makeNoise();
car3.makeNoise();

 

5. 클래스_ getters setters 개념 및 예제

getters/ setters 사용시 this에는 꼭 언더스코어(_)를 사용해야 콜스택 오류가 안남

this._height

//getters & setters
//클래스 -> 객체 인스턴스 생성
//프로퍼티 (constructor)을 접근하기위함

class Rectangle {
    constructor(height, width) {
        //underscore(_) : private ()로 분리해야함
        //[_ 없으면 오류] Maximum call stack size exceeded
        this._height = height; // getter, setter사용시 this에 접근하는 이름 앞에 '_' 붙이기
        this._width = width;
    }

    get width() {
        return this._width;
    }

    set width(value) {
        //value : 매개변수이름 (height의 value와 다름)
        //검증가능

        //검증 1: value가 음수이면 오류
        if (value <= 0) {
            console.log('[오류] 음수 불가능');
        } else if (typeof value !== Number) {
            console.log('[오류] 입력은 숫자만 가능');
        }

        this._width = value;
    }

    get height() {
        return this._height;
    }

    set height(value) {
        //value : 매개변수이름 (width의 value와 다름)
        //검증 1: value가 음수이면 오류
        if (value <= 0) {
            console.log('[오류] 음수 불가능');
        } else if (typeof value !== Number) {
            console.log('[오류] 입력은 숫자만 가능');
        }

        this._height = value;
    }

    getArea() {
        //넓이구하기
        const a = this._width * this._height;
        console.log(`넓이는 ${a}`);
    }
}

//인스턴스 생성
const rec1 = new Rectangle(10, 20);
const rec2 = new Rectangle(10, 30);

rec1.getArea();

 

6. 클래스_ getters setters 실전 연습

get 명칭 { return ~~}

set 명칭(value){ ~~}

//추가 요구사항
//1. modelName, modelYear, type, price 가져오는 메서드
//2. modelName, modelYear, type, price 세팅하는 메서드
//3. 만든 인스터스를 통해서 마지막에 set 해서 get하는 로직까지

class Car {
    constructor(modelName, modelYear, type, price) {
        this._modelName = modelName;
        this._modelYear = modelYear;
        this._type = type;
        this._price = price;
    }
    makeNoise() {
        console.log(`${this._modelName} 빵`);
    }

    get ModelName() {
        return this._modelName;
    }

    set ModelName(value) {
        //입력값의 검증이 가능함

        //유효성 검사
        if (value.length <= 0) {
            console.log('[오류] 입력값이 입력되지 않음');
        } else if (typeof value !== 'string') {
            console.log('[오류] 입력값이 문자형이 아님');
        }

        //검증이 완료된 경우에만 세팅
        this._modelName = value;
    }
}

const car1 = new Car('자동차1', '2023', 'A', 300);
const car2 = new Car('자동차2', '2022', 'B', 100);
const car3 = new Car('자동차3', '2021', 'C', 500);

//getter 예시
console.log(car1.ModelName);

//setter 예시
car1.ModelName = 1;
console.log(car1.ModelName); //[오류] 입력값이 문자형이 아님

7. 클래스_ 상속

- extends

- 부모(Animal) 메서드 재정의 = 오버라이딩

- 오버라이딩을 하면 부모클래스에게 알려주기 (super 키워드 사용)

//상속
//Class > 유산으로 내려주는 주요 기능!
//부모 <-> 자식

class Animal {
    //생성자
    constructor(name) {
        this.name = name;
    }

    //메서드
    speak() {
        console.log(`${this.name} says`);
    }
}

class Dog extends Animal {
    //extends 키워드 : Animal 클래스 상속

    //부모(Animal) 메서드 재정의 = 오버라이딩
    speak() {
        console.log(`${this.name} barks`);
    }
}

const cuttyPuppy01 = new Dog('복실이'); //부모 animal클래스의 name을 넣어줘야함
cuttyPuppy01.speak();
//추가요구사항
//전기차 클래스 : Car클래스의 상속을 받을 것
//

class Car {
    constructor(modelName, modelYear, type, price) {
        this.modelName = modelName;
        this.modelYear = modelYear;
        this.type = type;
        this.price = price;
    }
    makeNoise() {
        console.log(`${this.modelName} 빵`);
    }
}

//전기차 Class
class EVCar extends Car {
    //부모 클래스 : modelName, modelYear, type, price 4가지
    //type = 항상 전기차니깐 modelName, modelYear, price  3가지로 재정의 원함
    constructor(modelName, modelYear, price, chargeTime) {
        //부모클래스 (Car)에게도 알려줘야함
        //super(modelName, modelYear, type, price); //부모의 constructor 4가지를 그대로 넣기
        super(modelName, modelYear, 'e', price); //type -> 'e'로 작성
        this._chargeTime = chargeTime; //새로 추가한 부분
    }

    get chargeTime() {
        return this._chargeTime;
    }
    set chargeTime(value) {
        //검증
        this._chargeTime = value;
    }
}

const EVcar01 = new EVCar('전기차', '2024', 3000, 60);
console.log(EVcar01);
EVcar01.makeNoise();
console.log('------');

console.log(EVcar01.chargeTime);
EVcar01.chargeTime = 20;
console.log(EVcar01.chargeTime);

 

8. 클래스_ 정적 메소드

- static 사용

//static method (정적 메소드)
//class -> 객체를 만들기 위해 사용
// 다량, 안전, 정확하게

//계산기
class Calculator {
    static add(a, b) {
        // static을 사용해서 바로 사용하도록
        console.log('더하기');
        return a + b;
    }

    static substract(a, b) {
        // static을 사용해서 바로 사용하도록
        console.log('빼기');
        return a - b;
    }
}

console.log(Calculator.add(3, 4));
console.log(Calculator.substract(8, 4));

9. 클로저_소개 및 예시

- 클로저 : 함수 & 함수가 선언된 렉시컬 환경(아우터,레코드=> 스코프체이닝) 의 조합 

- 함수가 선언될 당시의 외부 변수 등의 정보 

- 렉시컬 스코프 : 어디에 '정의'했는지에 따라서 스코프(상위 스코프) 결정 

 

- 외부 렉시컬 환경에 대한 참조값=  outer 

- 함수의 정의가 평가되는 시점에 결정됨

 

- 클로저 & 렉시컬 환경

: 중첩함수가 종료한 경우, 외부함수의 변수를 여전히 참조할 수 있음

 

10. 클로저_ 클로저의 활용

-  전역변수로 선언시, 다른 사람이 코드를 수정할 위험이 있음

=> 클로저 이용! (변수는 초기화 x, 외부에서 접근할 수 없는 은닉한 값 , 의도되지 않는 변경도 걱정 x)

=> 변수 변경은 increase 함수 내부에서 가능하기 때문

//클로저 예시
const increase = (function () {
    //카운트 상태변수
    let num = 0;

    //클로저
    return function () {
        return ++num;
    };
})();

console.log(increase()); //1
console.log(increase()); //2

 

 

끝.

 

[출처]

1. 스파르타 코딩, JavaScript 문법 종합반 5주차 (1강-10강)

반응형