심벌은 항상 고유하며 객체 속성의 식별자로 사용할 수 있다.
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를 띄운다.
자바스크립트에는 다른 언어의 세터와 게터가 따로 존재 한다
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 }
이렇게 할 수 있다.