자바스크립트 복습 - 7

Stulta Amiko·2022년 5월 13일
0

자바스크립트 복습

목록 보기
7/12
post-thumbnail

심벌

심벌은 항상 고유하며 객체 속성의 식별자로 사용할 수 있다.

const plane = Symbol("Boeing");
console.log(plane); //Symbol(Boeing)

심벌값은 항상 고유하기 때문에 같은 값을 가진 심벌을 새롭게 만들어도 다른심벌과 겹치지 않는다. 이말인 즉슨 비교해도 true를 반환하지 않는다는 말이다.

const plane = Symbol("Boeing");
const clone = Symbol("Boeing");

console.log(plane == clone); //false
console.log(plane === clone); //false

객체에서 둘의 이름이 겹칠수도 있으니 심벌을 이용해서 고유하게 만들어 주면 이름이 겹치더라도 해결할 수 있다.

const plane = {
    "Boeing": "Company",
    "747": "Type",
    "747": "Type2",
};

for (information in plane) {
    console.log(information); // 747 Boeing
}

이런식으로 겹치는 경우

const plane = {
    [Symbol("Boeing")]: "Company",
    [Symbol("747")]: "Type",
    [Symbol("747")]: "Type2",
};

for (information in plane) {
    console.log(information); // undefined
}

const symbols = Object.getOwnPropertySymbols(plane);
console.log(symbols); //[ Symbol(Boeing), Symbol(747), Symbol(747) ]

이런식으로 심벌로 선언해주면 겹치지 않게된다.
그리고 심벌은 enumerable 하지 않으니 for in을 사용할수 없다.
객체 속성의 배열을 얻기 위해서는 Object.getOwnPropertySymbols()을 사용해서 배열을 가져온다.

const plane = {
    [Symbol("Boeing")]: "Company",
    [Symbol("747")]: "Type",
    [Symbol("747")]: "Type2",
};

const symbols = Object.getOwnPropertySymbols(plane);
const value = symbols.map(symbol => plane[symbol]);
console.log(value); //[ 'Company', 'Type', 'Type2' ]

이런식으로 심벌의 값을 가져올 수 있다.

클래스

클래스는 일차적으로 자바스크립트의 기존 프로토타입 기반 상속에 대한 문법적 설탕이다. 클래스 문법이 자바스크립트에 새로운 객체 지향 상속 모델을 도입하는것은 아니다.

라고 MDN은 설명하고 있다.

function plane(company, type) {
    this.company = company;
    this.type = type;
};

plane.prototype.fly = function() {
    console.log(`${this.company} ${this.type} fly`);
}

const boeing = new plane("Boeing", 747); 
const airbus = new plane("Airbus", 330);

boeing.fly(); //Boeing 747 fly
airbus.fly(); //Airbus 330 fly

plane의 프로토타입에 새 메서드를 추가해서 객체의 인스턴스들이 접근할 수 있도록 만들었다.

클래스를 선언하는 방법

class Plane() 클래스 선언
const boeing = class Plane{}; 클래스 표현식

클래스 선언 및 클래스 표현식은 호이스팅 되지 않는다.

호이스팅이란 무엇일까?

JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다. 반면 let과 const로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.

MDN에서는 호이스팅을 다음과 같이 소개하고 있다.

class Plane {
    constructor(company, type) {
        this.company = company;
        this.type = type;
    }
    fly() {
        console.log(`${this.company,this.type} fly`);
    }
    landing() {
        console.log(`${this.company,this.type} landing`);
    }
}

const boeing = new Plane("Boeing", 747);
const airbus = new Plane("Airbus", 330);

boeing.fly(); //747 fly
airbus.landing(); //330 landing

클래스를 이용해서 객체를 만드는 방법이다.
다른 언어의 클래스와 상당히 유사한 모습을 가지고 있다.
특이한점이라면 생성자를 생성하는 함수가 따로 존재한다.

정적 메서드

class Plane {
    constructor(company, type) {
        this.company = company;
        this.type = type;
    }
    static info() {
        console.log("static info print");
    }
}
const boeing = new Plane("Boeing", 747);

boeing.info(); //typeError boeing.info is not a funciton
Plane.info();  //static info print

클래스에 인스턴스가 아니라 Array.from이나 Array.of 처럼 인스턴스에 붙이는게 아니라 클래스 그 자체에 접근할 수 있는 정적메서드를 정의할 수 있다.
만약 인스턴스에 스태틱 메서드에 접근하려고 하면 TypeError를 띄운다.

set과 get

자바스크립트에는 다른 언어의 세터와 게터가 따로 존재 한다

class Plane {
    constructor(company, type) {
        this.company = company;
        this.type = type;
    }
    set changeType(type) {
        this.type = type;
        console.log(`change type to ${this.type}`);
    }
    get getType() {
        console.log(`return type : ${this.type}`);
        return this.type;
    }
}

const boeing = new Plane("Boeing", 747);
boeing.changeType = 767; //change type to 767
const type_1 = boeing.getType; //return type : 767
console.log(type_1); // 767

이런식으로 셋터와 겟터처럼 set과 get을 사용할 수 있다.

클래스 상속

상속은 extends 키워드를 이용해서 할 수 있다.

class Plane {
    constructor(company, type) {
        this.company = company;
        this.type = type;
    }
    fly() {
        console.log(`${this.type} is fly`);
    }
}

class Plane_2 extends Plane {
    constructor(company, type, operator) {
        this.company = company;
        this.type = type;
        this.operator = operator;
    }
}

const Delta_747 = new Plane_2("Boeing", 747, "Delta");

하지만 이런식으로 하면 Reference Error가 발생한다.
새로운 클래스에서 this를 사용하기 전에 super()를 사용해야한다.

class Plane {
    constructor(company, type) {
        this.company = company;
        this.type = type;
    }
    fly() {
        console.log(`${this.type} is fly`);
    }
}

class Plane_2 extends Plane {
    constructor(company, type, operator) {
        super(company, type);
        this.operator = operator;
    }
}

const Delta_747 = new Plane_2("Boeing", 747, "Delta");
Delta_747.fly(); //747 is fly

이런식으로 이용하면 오류 없이 잘된다.
Plane_2 클래스는 기존의 Plane 클래스의 모든 속성과 메서드를 상속했다.

배열 확장하기

첫번째 값은 교실이름이고 나머지는 학생인 클래스를 만들자

class Classroom extends Array {
    constructor(name, ...students) {
        super(...students);
        this.name = name;
    }
    add(student) {
        this.push(student);
    }
}

const myClass = new Classroom('1', { name: "jo", mark: 6 }, { name: "ko", mark: 7 }, { name: "bi", mark: 8 }, { name: "chi", mark: 9 }, );

myClass.add({ name: "tho", mark: 10 })
console.log(myClass[4]); //{ name: 'tho', mark: 10 }

for (const student of myClass) {
    console.log(student);
}

실행결과
{ name: 'jo', mark: 6 }
{ name: 'ko', mark: 7 }
{ name: 'bi', mark: 8 }
{ name: 'chi', mark: 9 }
{ name: 'tho', mark: 10 }

이렇게 할 수 있다.

0개의 댓글