Skip to content

Latest commit

Β 

History

History
387 lines (270 loc) Β· 13.4 KB

step6.md

File metadata and controls

387 lines (270 loc) Β· 13.4 KB

λ¬Έμ„œ λͺ©λ‘μœΌλ‘œ λŒμ•„κ°€κΈ°

STEP 6

πŸ’‘μ§ˆμ˜μ‘λ‹΅μ€ https://github.com/pul8219/TIL Issues νƒ­μ˜ μ•Œλ§žμ€ step μ΄μŠˆμ•ˆμ— λ‚¨κ²¨μ£Όμ„Έμš”. ➑️ Issueνƒ­μœΌλ‘œ 이동

보좩 ν•„μš”

  • μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ μƒμ„±μž new

  • μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν”„λ‘œν† νƒ€μž… 기반 μ–Έμ–΄ prototype ν”„λ‘œνΌν‹°?

  • let{...} = ?; 이런 문법!

  • ꡬ쑰 λΆ„ν•΄ ν• λ‹Ή?

  • ${} 문법 ${} ν‘œν˜„μ‹μ€ 처리된 값을 λ¬Έμžμ—΄λ‘œ λ°˜ν™˜ν•œλ‹€.

  • 엄격 λͺ¨λ“œ

  • 객체λ₯Ό λ§Œλ“€ λ•Œ function이 μƒκΈ΄λ‹€λŠ” 것? - Object Function{}

  • 클래슀의 ν˜Έμ΄μŠ€νŒ…μ€ μ–΄λ–»κ²Œ λ˜λ‚˜?mdn에선 μ•„λ‹ˆλΌν•˜κ³  λ‹€λ₯Έ μžλ£Œμ—μ„  말을 λœλ‹€κ³ ν•˜κ³  ν˜Όλž€...

Javascript

λͺ©μ°¨

μžλ°”μŠ€ν¬λ¦½νŠΈμ™€ Prototype(ν”„λ‘œν† νƒ€μž…)

(μ•„λž˜ λ‚΄μš©μ€ MDN에 λ‚˜μ™€μžˆλŠ” μ„€λͺ…을 μ΄ν•΄ν•˜λ©° μ •λ¦¬ν–ˆλ‹€.)

  • μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 객체의 μ›ν˜•μΈ prototype을 μ΄μš©ν•˜μ—¬ μƒˆλ‘œμš΄ 객체λ₯Ό μƒμ„±ν•˜λŠ” prototype 기반 언어이닀. '상속'μ΄λž€ κ°œλ…μ΄ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€. λ‹€λ§Œ μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν΄λž˜μŠ€μ™€ λΉ„μŠ·ν•˜κ²Œ λ™μž‘ν•˜κ²Œλ” ν‰λ‚΄λ‚΄λŠ” μ—¬λŸ¬ 기법듀을 가지고 μžˆλ‹€. (ES6μ—μ„œ class ν‚€μ›Œλ“œκ°€ λ„μž…λμ§€λ§Œ μ΄λŠ” μ‚¬μš©ν•˜κΈ° μ‰½κ²Œ ν•˜κΈ°μœ„ν•΄ λ„μž…λœ 것일뿐 μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μ—¬μ „νžˆ prototype 기반의 언어이닀. λ”°λΌμ„œ 클래슀 기반 언어인 Java와 C++ λ₯Ό λ‹€λ£¨λ˜ κ°œλ°œμžμ—κ² μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ μ΄λŸ¬ν•œ 방식은 λ‹€μ†Œ λ‹Ήν™©μŠ€λŸ½κ²Œ 느껴질 수 있음 JS μ°Έ μ•Œμˆ˜λ‘ κΆκΈˆν•œ 친ꡬ)

  • μƒμ†μ˜ κ΄€μ μ—μ„œ μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ μœ μΌν•œ μƒμ„±μžλŠ” '객체'뿐이닀. 각각의 κ°μ²΄λŠ” [[Prototype]]μ΄λΌλŠ” private 속성을 κ°€μ§€λŠ”λ° μžμ‹ μ˜ prototype이 λ˜λŠ” λ‹€λ₯Έ 객체λ₯Ό 가리킨닀. λ˜ν•œ 각각 객체듀은 μžμ‹ μ˜ prototype(μ›ν˜•μ΄λΌκ³  이해)λ₯Ό 가지고 μžˆλ‹€.

  • 객체의 prototype은 λ‹€λ₯Έ prototype 객체λ₯Ό 바라보고, 이것이 반볡(prototype chain)λ˜λ‹€κ°€ prototype이 null인 κ°μ²΄μ—μ„œ 끝이 λ‚œλ‹€. null은 λ”μ΄μƒμ˜ prototype이 μ—†λ‹€κ³  μ •μ˜λ˜λ©°, prototype chain의 쒅점역할을 ν•œλ‹€.

  • 예λ₯Ό λ“€μ–΄, μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ λͺ¨λ“  객체듀은 prototype chain μ΅œμƒμœ„μ— μžˆλŠ” Object의 μΈμŠ€ν„΄μŠ€λ“€λ‘œ 이해할 수 μžˆλ‹€.

prototype 이해에 도움이 많이 된 자료 https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67

ES6μ—μ„œ λ„μž…λœ Class

  • ES6 μ΄μ „κΉŒμ§€λŠ” λΉ„μŠ·ν•œ μ’…λ₯˜μ˜ 객체λ₯Ό 많이 λ§Œλ“€μ–΄λ‚΄κΈ° μœ„ν•΄ μƒμ„±μžλ₯Ό μ‚¬μš©ν•΄μ™”μŒ
  • ES6μ—μ„œ 클래슀 문법이 좔가됨
  • ES6μ—μ„œλ„ 일정 뢀뢄은 ν”„λ‘œν† νƒ€μž…μ„ ν™œμš©ν•˜κ³  있기 λ•Œλ¬Έμ—, ES5에 μžˆλŠ” 클래슀λ₯Ό 흉내내기 μœ„ν•œ(classalike) κ΅¬ν˜„ 방식은 μ•Œκ³  μžˆλŠ” 것이 μ’‹μŒ
  • ν΄λž˜μŠ€λŠ” ν˜Έμ΄μŠ€νŒ…μ΄ λ˜μ§€λ§Œ uninitialized둜 μ΄ˆκΈ°ν™”λ˜κΈ° λ•Œλ¬Έμ— μ„ μ–Έ 전에 μ‚¬μš©ν•˜λ €κ³  ν•˜λ©΄ Reference Errorκ°€ λ°œμƒν•œλ‹€.
  • 클래슀의 bodyλŠ” 엄격λͺ¨λ“œ(strict mode)둜 μ‹€ν–‰λœλ‹€.
  • Class의 bodyμ—μ„œλŠ” λ©”μ„œλ“œλ§Œ μ„ μ–Έ κ°€λŠ₯ν•˜λ‹€.(λ©€λ²„λ³€μˆ˜λŠ” μ„ μ–Έ λΆˆκ°€)
  • JSμ—μ„œ ν΄λž˜μŠ€λŠ” νŠΉλ³„ν•œ ν•¨μˆ˜μ΄λ‹€
  • prototype 기반의 상속 흉내?보닀 λͺ…λ£Œν•˜κ³  νŽΈμ˜λ†’κ²Œ μ‚¬μš©ν•  수 μžˆλ„λ‘ 문법을 μ œκ³΅ν•˜μ—¬ Syntatic Sugar 라 함
// 이전에 μ‚¬μš©ν•˜λ˜ μƒμ„±μž ν•¨μˆ˜ 방식
// 관둀상 μƒμ„±μž ν•¨μˆ˜μ˜ 첫 λ¬ΈμžλŠ” λŒ€λ¬Έμžλ‘œ ν‘œκΈ°!

function Book(title, writer) {
  this.title = title;
  this.writer = writer;
}

var book1 = new Book('λ°œμΉΈλ°˜λ„', 'μ—¬ν–‰κ°€');
var book2 = new Book('μ‡Όμ½”μ˜ λ―Έμ†Œ', 'μ΅œμ€μ˜');

console.log(book1.title + '-' + book1.writer);
console.log(book2.title + '-' + book2.writer);
// 클래슀 λΈ”λ‘μ—μ„œλŠ” λ³„λ„μ˜ λ¬Έλ²•μœΌλ‘œ μ½”λ“œλ₯Ό μž‘μ„±ν•΄μ•Όν•œλ‹€. ν•¨μˆ˜ ν˜Ήμ€ 객체 λ‚΄λΆ€μ—μ„œ μ‚¬μš©ν•˜λŠ” 문법과 ν—·κ°ˆλ¦¬μ§€ μ•Šλ„λ‘ μ£Όμ˜ν•  것
class Person{
	console.log('hello');
}
// μ—λŸ¬: Unexpected token

class Person{
	name: "nana",
	email: "[email protected]"
}
// μ—λŸ¬: Unexpected token

Class μ •μ˜ 방법

  1. class 선언식
// Class μ •μ˜ 방법 - 1. 클래슀 μ„ μ–Έ
class Book(){
	constructor(title, writer){
		this.title = title;
		this.writer = writer;
	}
}
  1. class ν‘œν˜„μ‹
  • 읡λͺ…μ˜ class도 μ •μ˜ κ°€λŠ₯
// Class μ •μ˜ 방법 - 2. 클래슀 ν‘œν˜„μ‹

// 읡λͺ…(unnamed) 클래슀 μ„ μ–Έ μ˜ˆμ‹œ
let Book = class {
  constructor(title, writer) {
    this.title = title;
    this.writer = writer;
  }
};

const book1 = new Book('μ‡Όμ½”μ˜ λ―Έμ†Œ', 'μ΅œμ€μ˜');
console.log(book1.title); // "μ‡Όμ½”μ˜ λ―Έμ†Œ"
// 이름을 κ°–λŠ” 클래슀
let Book = class Book1 {
  constructor(title, writer) {
    this.title = title;
    this.writer = writer;
  }
};
console.log(Book.name); //"Book1"

MDN 좜처 A class expression is another way to define a class. Class expressions can be named or unnamed. The name given to a named class expression is local to the class's body. (it can be retrieved through the class's (not an instance's) name property, though). 첫 λ¬Έμž₯ λΉΌκ³  무슨 의미?

μΈμŠ€ν„΄μŠ€ 생성

  • new μ—°μ‚°μžμ™€ ν•¨κ»˜ constructor(μƒμ„±μž)λ₯Ό ν˜ΈμΆœν•œλ‹€.
  • new μ—°μ‚°μž 없이 constructorλ₯Ό ν˜ΈμΆœν•˜λ©΄ νƒ€μž… μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.
class Foo {}
const foo = new Foo(); // newλ₯Ό 톡해 μΈμŠ€ν„΄μŠ€ 생성

console.log(Foo === Foo.prototype.constructor); //true

μƒμ„±μž

= Constructor

  • μƒμ„±μž λ©”μ†Œλ“œλŠ” 객체의 생성과 μ΄ˆκΈ°ν™”λ₯Ό ν•˜λŠ” νŠΉλ³„ν•œ λ©”μ†Œλ“œλ‘œ 클래슀 내에 constructor 이름을 κ°–λŠ” λ©”μ†Œλ“œλŠ” ν•˜λ‚˜μ—¬μ•Όν•œλ‹€.
  • constructorλŠ” μΈμŠ€ν„΄μŠ€ 생성과 λ™μ‹œμ— 클래슀 ν”„λ‘œνΌν‹°μ˜ 생성과 μ΄ˆκΈ°ν™”λ₯Ό μ‹€ν–‰ν•œλ‹€.
class Foo {} //constructorλ₯Ό μƒλž΅ν•˜λ©΄ constructor() {}κ°€ μžλ™μœΌλ‘œ ν¬ν•¨λœ κ²ƒμ²˜λŸΌ λ™μž‘ν•œλ‹€.

const foo = new Foo();
console.log(foo); // Foo {}

foo.num = 1; // 클래슀 ν”„λ‘œνΌν‹°μ˜ 동적 ν• λ‹Ή 및 μ΄ˆκΈ°ν™”κ°€ κ°€λŠ₯ν•˜λ‹€
console.log(foo); // Foo { num: 1 }

Getter, Setter

// Getter, Setter
class Foo {
  constructor(bar) {
    this.bar = bar;
  }
  get met() {
    return this.bar;
  }
  set met(newBar) {
    this.bar = newBar;
  }
}

let foo = new Foo('hello');
console.log(foo.bar); // "hello"
console.log(foo.met); // "hello"
foo.met = 'hi';
console.log(foo.met); // "hi"

클래슀 ν•„λ“œ(class field)

클래슀 블둝 μ•ˆμ—μ„œ ν• λ‹Ή μ—°μ‚°μž(=)λ₯Ό 톡해 μΈμŠ€ν„΄μŠ€ 속성을 지정할 수 μžˆλŠ” 문법(아직 정식 ν‘œμ€€μœΌλ‘œ μ±„νƒλœ κΈ°λŠ₯은 μ•„λ‹˜)

클래슀 상속

ν•œ 클래슀λ₯Ό λ‹€λ₯Έ ν΄λž˜μŠ€κ°€ μƒμ†ν•˜μ—¬ λ‹€λ₯Έ ν΄λž˜μŠ€μ—μ„œ μž¬μ‚¬μš©ν•  수 있음

  • μžμ‹ 클래슀λ₯Ό 톡해 λΆ€λͺ¨ 클래슀의 정적 λ©”μ†Œλ“œμ™€ 정적 속성을 μ‚¬μš©ν•  수 μžˆλ‹€.
  • λΆ€λͺ¨ 클래슀의 μΈμŠ€ν„΄μŠ€ λ©”μ†Œλ“œμ™€ μΈμŠ€ν„΄μŠ€ 속성을 μžμ‹ 클래슀의 μΈμŠ€ν„΄μŠ€μ—μ„œ μ‚¬μš©ν•  수 μžˆλ‹€.
// 상속
class animal {
  // λΆ€λͺ¨ 클래슀 Animal
  static region = 'KR';
  static jump() {
    console.log('jump!');
  }
  stop() {
    console.log('stop');
  }
}

class cat extends animal {
  // μžμ‹ 클래슀 Cat
}

cat.jump(); // μžμ‹ν΄λž˜μŠ€λ₯Ό 톡해 λΆ€λͺ¨ν΄λž˜μŠ€μ˜ μ •μ λ©”μ†Œλ“œ μ‚¬μš© κ°€λŠ₯
console.log(cat.region); // μžμ‹ν΄λž˜μŠ€λ₯Ό 톡해 λΆ€λͺ¨ν΄λž˜μŠ€μ˜ 정적 속성 μ‚¬μš© κ°€λŠ₯

let c = new cat();
c.stop(); // μžμ‹ν΄λž˜μŠ€μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό 톡해 λΆ€λͺ¨ν΄λž˜μŠ€μ˜ μΈμŠ€ν„΄μŠ€ λ©”μ†Œλ“œμ™€ μΈμŠ€ν„΄μŠ€ 속성을 μ‚¬μš© κ°€λŠ₯

super

μžμ‹ ν΄λž˜μŠ€μ— λΆ€λͺ¨ ν΄λž˜μŠ€μ— μžˆλŠ” 속성과 같은 μ΄λ¦„μ˜ 속성이 μžˆλŠ” 경우 λ¬Έμ œκ°€ 될 수 μžˆλŠ”λ°, superλ₯Ό μ“°λ©΄ λΆ€λͺ¨ 클래슀의 λ©”μ†Œλ“œμ— 직접 μ ‘κ·Όν•  수 μžˆλ‹€.

super ν‚€μ›Œλ“œμ˜ λ™μž‘ 방식 TODO

// super
class writing {
  getMedia() {
    return 'book';
  }
}

class essay extends writing {
  getMedia() {
    return super.getMedia() + ' or brunch';
  }
}

let e = new essay();
console.log(e.getMedia()); // "book or brunch"

클래슀 상속과 ν”„λ‘œν† νƒ€μž… 상속 비ꡐ

TODO

Q&A

νŒ€μ›λ“€μ˜ μŠ€ν„°λ”” κ²°κ³Όλ¬Ό

μ€μ˜ https://eyabc.github.io/Doc/dev/core-javascript/%ED%81%B4%EB%9E%98%EC%8A%A4.html#%EC%9E%AC%EC%82%AC%EC%9A%A9

ν˜•μš± https://github.com/khw970421/js-interview/blob/master/const/project6.js

μ •μ›… https://jeongshin.github.io/JeongShin_Blog/TIL/study/JavaScript.html#step-6

노원 https://github.com/quavious/hell_script/blob/master/chapter6.js

유림

to ν˜•μš±

Q. 잘 μ½μ—ˆμŠ΅λ‹ˆλ‹€. μ €λŠ” 이번주 μ—°μž₯ν•΄μ„œ 아직 곡뢀가 덜 λ˜μ–΄μžˆλŠ” μƒνƒœμΈλ° ν˜•μš±λ‹˜κΊΌ μ­‰ λ³΄λ‹ˆκΉŒ 이해도 되고 도움도 많이 λμŠ΅λ‹ˆλ‹€. 객체가 μ°Έμ‘°λ˜μ–΄ 값이 같이 λ³€κ²½λ˜λŠ” κ²½μš°λ„ μ•Œμ•„κ°‘λ‹ˆλ‹€

console.log(objA1.x); //객체λ₯Ό λ³΅μ‚¬ν•˜λ―€λ‘œ 10은 λ³€ν•˜μ§€μ•Šκ³  10으둜 좜λ ₯

ν˜Ήμ‹œ μœ„ λΆ€λΆ„μ—μ„œ 객체λ₯Ό λ³΅μ‚¬ν•œλ‹€λŠ” ν‘œν˜„μ΄ λ§žλŠ” κ²ƒμΈκ°€μš”? μ•„λ‹ˆλ©΄ 객체의 x ν”„λ‘œνΌν‹°μ˜ κ°’λ§Œ λ³΅μ‚¬ν•˜λŠ” κ²ƒμΈκ°€μš”? (μ œκ°€ js μ™•μ΄ˆλ³΄λΌμ„œ μ—¬μ­ˆμ–΄λ΄…λ‹ˆλ‹€...)

+++ μ˜€λ²„μ›ŒμΉ˜λΌλ‹ˆ... @eyabc μ’‹μ•„ν•˜μ‹€ μ‹€μƒν™œ μ˜ˆμ‹œλ„€μš” γ…‹γ…‹γ…‹γ…‹μ‹ μ„ ν•©λ‹ˆλ‹€ πŸ‘

A. console.log(objA1.x) //객체λ₯Ό λ³΅μ‚¬ν•˜λ―€λ‘œ 10은 λ³€ν•˜μ§€μ•Šκ³  10으둜 좜λ ₯

이뢀뢄 같은 κ²½μš°λŠ” μ •ν™•νžˆλŠ” μ œκ°€ 쑰금 μ„€λͺ…이 λΆ€μ‘±ν•˜κ³  잘λͺ»λœκ²ƒκ°™μŠ΅λ‹ˆλ‹€. pul8219λ‹˜ λ§λŒ€κ³  객체의 x의 값이 λ³΅μ‚¬λœλ‹€κ³  μ„€λͺ…ν•˜λŠ”κ²ƒμ΄ λ§žλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. λ”°λΌμ„œ μ •ν™•νžˆλŠ”

let objA1={ x:10 } let value=objA1.x; //객체 x의 ν”„λ‘œνΌν‹° κ°’ 자체λ₯Ό λ³΅μ‚¬ν•˜μ—¬ value에 μ €μž₯(μ°Έμ‘° x) value=100; //value에 μ €μž₯된 κ°’ 10을 100으둜 μˆ˜μ • console.log(objA1.x) // objA1.xλŠ” value의 변화에 영ν–₯이 없이 값은 10으둜 μœ μ§€ 이게 λ§žλ‹€κ³ μƒκ°ν•©λ‹ˆλ‹€. 저도 μˆ˜μ •μ„ ν”Όλ“œλ°±ν•΄μ•Όκ² λ„€μš” κ°μ‚¬ν•©λ‹ˆλ‹€.

to 노원

잘 λ΄€μŠ΅λ‹ˆλ‹€. μ½”λ“œλ‘œ λ‹€μ–‘ν•œ 예제λ₯Ό λ³Ό 수 μžˆμ–΄μ„œ 쒋은 것 κ°™μ•„μš”. 곡뢀가 더 ν•„μš”ν•΄μ„œ μžμ„Έν•œκ±΄ @eyabc λ‹˜μ˜ μœ„μ— 질문&λ‹΅λ³€ 보고 많이 λ°°μš°κ² μŠ΅λ‹ˆλ‹€.

to μ •μ›…

Step6 잘 μ½μ—ˆμŠ΅λ‹ˆλ‹€!

to μ€μ˜

클래슀의 μ „λ°˜μ μΈ λ‚΄μš©, ν΄λž˜μŠ€λ„ ν˜Έμ΄μŠ€νŒ…μ΄ λœλ‹€λŠ” 점, 그리고 상속, super λ“±μ˜ λ‚΄μš©μ„ 잘 이해할 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. 양이 정말 λ°©λŒ€ν•˜λ„€μš”πŸ‘ μ΄λ ‡κ²Œ 높은 질의 λ¬Έμ„œλ₯Ό μœ„ν•΄μ„œ 저도 미리미리 ν•˜κ³  μ‹œκ°„νˆ¬μžλ₯Ό 더 ν•΄μ•Όκ² μŠ΅λ‹ˆλ‹€

쀀일 리뷰)

  1. 이 뢀뢄은 잘λͺ»λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

정적 λ©”μ„œλ“œμ—μ„œλ„ thisλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

class Foo {}
Foo.a = 10;
Foo.b = 20;
Foo.c = function () {
  return this.a + this.b;
};
console.log(Foo.c()); // 30

  1. 참고둜 private ν•„λ“œμ™€ λ©”μ†Œλ“œλŠ” μƒμ†λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ μ›λž˜ ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ μƒμœ„ 클래슀의 ν•„λ“œμ™€ λ©”μ†Œλ“œμ— μ ‘κ·Όν•˜κΈ° μœ„ν•΄μ„  protected λΌλŠ” μ ‘κ·Όμ œν•œμžλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€. 그런데 JSμ—λŠ” private만 있고 protectedκ°€ μ—†κΈ° λ•Œλ¬Έμ— private으둜 μ„ μ–Έλœ 것은 μ•„μ˜ˆ μƒμ†λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

참고둜 superλŠ” 항상 μƒμ„±μž μ΅œμƒλ‹¨μ—μ„œ μ‚¬μš©λ˜μ–΄μ•Όν•©λ‹ˆλ‹€. super보닀 μœ„μ— μžˆλŠ” ꡬ문이 μžˆμ„ 경우 μ—λŸ¬κ°€ λ°œμƒν•©λ‹ˆλ‹€.

  1. ES5와 ES6κ°€ μ •ν™•νžˆ μ–΄λ–»κ²Œ λ‹€λ₯Έμ§€ μ„€λͺ…ν•˜λŠ” κΈ€μž…λ‹ˆλ‹€.

https://www.bsidesoft.com/5370

핡심은 λ°”λ‘œ "상속" μž…λ‹ˆλ‹€.

ES5둜 ES6μ—μ„œ μ‚¬μš©ν•˜λŠ” 상속을 μ™„λ²½ν•˜κ²Œ 흉내 λ‚΄λŠ” 것은 λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€.

Reference

https://poiemaweb.com/es6-class

https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67