Object-Oriented Programming (OOP) with javascript

vancouverยท2023๋…„ 6์›” 29์ผ
0

javascript์ดํ•ดํ•˜๊ธฐ

๋ชฉ๋ก ๋ณด๊ธฐ
19/22

What is Object-Oriented Programming?

๐Ÿ‘‰ ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(OOP)์€ ๊ฐ์ฒด ๊ฐœ๋…์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„์ž…๋‹ˆ๋‹ค.


๐Ÿ‘‰ ์šฐ๋ฆฌ๋Š” ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜„์‹ค ์„ธ๊ณ„๋‚˜ ์ถ”์ƒ์ ์ธ ํŠน์ง•์„ ๋ชจ๋ธ๋ง(๋ฌ˜์‚ฌ)ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ‘‰ ๊ฐ์ฒด๋Š” ๋ฐ์ดํ„ฐ(์†์„ฑ)์™€ ์ฝ”๋“œ(๋ฉ”์„œ๋“œ)๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ๋ฐ์ดํ„ฐ์™€ ํ•ด๋‹น ๋™์ž‘์„ ํ•˜๋‚˜์˜ ๋ธ”๋ก์œผ๋กœ ๋ฌถ์–ด์ค๋‹ˆ๋‹ค.


๐Ÿ‘‰ ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๊ฐ์ฒด๋Š” ๋…๋ฆฝ์ ์ธ ์ฝ”๋“œ ์กฐ๊ฐ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ‘‰ ๊ฐ์ฒด๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ตฌ์„ฑ ์š”์†Œ์ด๋ฉฐ ์„œ๋กœ ์ƒํ˜ธ์ž‘์šฉํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ‘‰ ์ƒํ˜ธ์ž‘์šฉ์€ ๊ณต๊ฐœ ์ธํ„ฐํŽ˜์ด์Šค(API)๋ฅผ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐ์ฒด ์™ธ๋ถ€์˜ ์ฝ”๋“œ๊ฐ€ ๊ฐ์ฒด์™€ ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•ด ์•ก์„ธ์Šคํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.


๐Ÿ‘‰ ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ์ฝ”๋“œ๋ฅผ ๊ตฌ์กฐํ™”ํ•˜์—ฌ ์œ ์—ฐํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฝ๋„๋ก ๊ฐœ๋ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด "์ŠคํŒŒ๊ฒŒํ‹ฐ ์ฝ”๋“œ"๋ฅผ ํ”ผํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ์กฐ์งํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ถ”์ƒํ™”(Abstraction): ๊ตฌํ˜„์— ์‹ค์ œ๋กœ ์ค‘์š”ํ•˜์ง€ ์•Š์€ ์„ธ๋ถ€์‚ฌํ•ญ์„ ๋ฌด์‹œํ•˜๊ฑฐ๋‚˜ ์ˆจ๊ธฐ๋Š” ๊ฒƒ์œผ๋กœ, ๊ตฌํ˜„ํ•˜๋ ค๋Š” ๋Œ€์ƒ์— ๋Œ€ํ•œ ๊ฐœ์š”์ ์ธ ๊ด€์ ์„ ์–ป์„ ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. ๊ตฌํ˜„์— ์ค‘์š”ํ•˜์ง€ ์•Š์€ ์„ธ๋ถ€์‚ฌํ•ญ์— ์–ฝ๋งค์ด์ง€ ์•Š๊ณ  ๊ตฌํ˜„์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

  • ์บก์Šํ™”(Encapsulation): ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ์†์„ฑ๊ณผ ๋ฉ”์„œ๋“œ๋ฅผ ๋น„๊ณต๊ฐœ(private)๋กœ ์œ ์ง€ํ•˜์—ฌ ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋ฉ”์„œ๋“œ๋Š” ๊ณต๊ฐœ ์ธํ„ฐํŽ˜์ด์Šค(API)๋กœ ๋…ธ์ถœ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ๋™์ž‘์„ ์ˆจ๊ธฐ๊ณ  ๊ฐ์ฒด์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๊ธฐ ์œ„ํ•œ ๊ณต๊ฐœ๋œ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ƒ์†(Inheritance): ํŠน์ • ํด๋ž˜์Šค์˜ ๋ชจ๋“  ์†์„ฑ๊ณผ ๋ฉ”์„œ๋“œ๋ฅผ ์ž์‹ ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋กํ•˜์—ฌ ํด๋ž˜์Šค๊ฐ„์— ๊ณ„์ธต์ ์ธ ๊ด€๊ณ„๋ฅผ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ณตํ†ต ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•˜๊ณ  ํ˜„์‹ค ์„ธ๊ณ„์˜ ๊ด€๊ณ„๋ฅผ ๋ชจ๋ธ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋‹คํ˜•์„ฑ(Polymorphism): ์ž์‹ ํด๋ž˜์Šค๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์†๋ฐ›์€ ๋ฉ”์„œ๋“œ๋ฅผ ๋ฎ์–ด์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [๋” ๋ณต์žกํ•˜์ง€๋งŒ, ์šฐ๋ฆฌ์˜ ๋ชฉ์ ์—๋Š” ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.]

"CLASSICAL OOP": CLASSES


๐Ÿ‘‰ ํ–‰๋™(๋ฉ”์„œ๋“œ)์€ ํด๋ž˜์Šค์—์„œ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๋กœ ๋ณต์‚ฌ๋ฉ๋‹ˆ๋‹ค.


๐Ÿ‘‰ ๊ฐ์ฒด(์ธ์Šคํ„ด์Šค)๋Š” ๋ธ”๋ฃจํ”„๋ฆฐํŠธ์ฒ˜๋Ÿผ ์ž‘๋™ํ•˜๋Š” ํด๋ž˜์Šค์—์„œ ์ธ์Šคํ„ด์Šคํ™”๋ฉ๋‹ˆ๋‹ค.

OOP IN JS: PROTOTYPES


๐Ÿ‘‰ ํ–‰๋™์€ ์—ฐ๊ฒฐ๋œ ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด๋กœ ์œ„์ž„๋ฉ๋‹ˆ๋‹ค.


๐Ÿ‘‰ ๊ฐ์ฒด๋Š” ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด์— ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.


๐Ÿ‘‰ ํ”„๋กœํ† ํƒ€์ž… ์ƒ์†(Prototypal inheritance): ํ”„๋กœํ† ํƒ€์ž…์—๋Š” ํ•ด๋‹น ํ”„๋กœํ† ํƒ€์ž…์— ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  ๊ฐ์ฒด์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ(๋™์ž‘)๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

์ƒ์„ฑ์ž ํ•จ์ˆ˜(Constructor functions)


๐Ÿ‘‰ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค.
๐Ÿ‘‰ ์ด ๋ฐฉ๋ฒ•์€ ๋ฐฐ์—ด(Array), ๋งต(Map), ์„ธํŠธ(Set)๊ณผ ๊ฐ™์€ ๋‚ด์žฅ ๊ฐ์ฒด๊ฐ€ ์‹ค์ œ๋กœ ๊ตฌํ˜„๋˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค

ES6 Classes


๐Ÿ‘‰ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๊ตฌ๋ฌธ์˜ ํ˜„๋Œ€์ ์ธ ๋Œ€์•ˆ์ž…๋‹ˆ๋‹ค.
๐Ÿ‘‰ "๋ฌธ๋ฒ•์  ์„คํƒ•(Syntactic sugar)": ES6 ํด๋ž˜์Šค๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ ์ •ํ™•ํžˆ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
๐Ÿ‘‰ ES6 ํด๋ž˜์Šค๋Š” "ํด๋ž˜์‹ํ•œ OOP"์˜ ํด๋ž˜์Šค์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Object.create()


๐Ÿ‘‰ ๊ฐ์ฒด๋ฅผ ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด์— ์—ฐ๊ฒฐํ•˜๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•˜๊ณ  ์ง๊ด€์ ์ธ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค

The 4 pillars of OOP are still valid!

๐Ÿ‘† OOP์˜ 4๊ฐ€์ง€ ์›์น™์€ ์—ฌ์ „ํžˆ ์œ ํšจํ•ฉ๋‹ˆ๋‹ค!


๐Ÿ‘‰ ์ถ”์ƒํ™”
๐Ÿ‘‰ ์บก์Šํ™”
๐Ÿ‘‰ ์ƒ์†
๐Ÿ‘‰ ๋‹คํ˜•์„ฑ

Constructor Functions and the new Operator

const Person = function (firstName, birthYear) { // ์ฒญ์‚ฌ์ง„์„ ๋งŒ๋“ฌ
  // Instance properties
  this.firstName = firstName;
  this.birthYear = birthYear;

  // Never to this (์ฒญ์‚ฌ์ง„์•ˆ์— function์„ ์ด๋Ÿฐ์‹์œผ๋กœ ๋„ฃ์œผ๋ฉด ์•ˆ๋œ๋‹ค.)
  //   this.calcAge = function () {
  //     console.log(2037 - this.birthYear);
  //   };
};

const jonas = new Person(`Jonas`, 1991);
console.log(jonas); // Person {firstName: 'jonas', birthYear: 1991}

// 1. New {} is created
// 2. function is called, this = {}
// 3. {} linked to prototype
// 4. function automatically return {}

const matilda = new Person(`Matilda`, 2017);
const van = new Person(`van`, 1975); // Person {firstName: 'van', birthYear: 1975}
console.log(matilda, van);

console.log(jonas instanceof Person); // true

Prototypes

// Prototypes
console.log(Person.prototype);
/* {constructor: ฦ’}
calcAge: ฦ’ ()
species: "Homo Sapiens"
constructor: ฦ’ (firstName, birthYear)
[[Prototype]]: Object */

Person.prototype.calcAge = function () {
  console.log(2037 - this.birthYear);
};

jonas.calcAge(); // 46
matilda.calcAge(); // 20

console.log(jonas.__proto__);
/* {calcAge: ฦ’, constructor: ฦ’}
    calcAge: ฦ’ ()
    constructor: ฦ’ (firstName, birthYear)
    [[Prototype]]: Object */
console.log(jonas.__proto__ === Person.prototype); // true

console.log(Person.prototype.isPrototypeOf(jonas)); // true
console.log(Person.prototype.isPrototypeOf(matilda)); // true
console.log(Person.prototype.isPrototypeOf(Person)); // false

// .prototypeOfLinkedObjects

Person.prototype.species = `Homo Sapiens`;
console.log(jonas.species, matilda.species); // Homo Sapiens Homo Sapiens

console.log(jonas.hasOwnProperty(`firstName`)); // true
console.log(jonas.hasOwnProperty(`species`)); // false (prototype ์•ˆ์— ์žˆ์Œ์œผ๋กœ false)

console.log(jonas);
/* Person {firstName: 'Jonas', birthYear: 1991}
birthYear: 1991
firstName: "Jonas"
[[Prototype]]: Object
calcAge: ฦ’ ()
species: "Homo Sapiens"
constructor: ฦ’ (firstName, birthYear)
[[Prototype]]: Object */

Prototypal Inheritance and The Prototype Chain (ํ”„๋กœํ† ํƒ€์ž… ์ƒ์†๊ณผ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ)

The new operator :
1. ๋นˆ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
2. ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ํ˜ธ์ถœ์—์„œ this ํ‚ค์›Œ๋“œ๋Š” ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.
3. ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ํ”„๋กœํ† ํƒ€์ž… ์†์„ฑ๊ณผ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค (proto ์†์„ฑ).
4. ์ƒˆ๋กœ์šด ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ํ˜ธ์ถœ๋กœ๋ถ€ํ„ฐ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

Prototypal Inheritance on Built-In Objects

console.log(jonas.__proto__);

console.log(jonas.__proto__.__proto__);

console.log(jonas.__proto__.__proto__.__proto__); // null

console.dir(Person.prototype.constructor);

const arr = [3, 6, 6, 5, 6, 9, 9];
console.log(arr.__proto__);
console.log(arr.__proto__ === Array.prototype); //  true (Array.prototype์ด๋ž€ ๋ณต์ œํ’ˆ์„ ๋งŒ๋“ฌ ๋ฐฐํ›„์— ์‚ฌ์šฉ๊ฐ€๋Šฅ)

console.log(arr.__proto__.__proto__);

Array.prototype.unique = function () { // ์ƒˆ๋กœ์šด method๋ฅผ ์ƒ์„ฑ (unique) (โŒ์ƒˆ๋กœ์šด ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋“œ๋Š”๊ฑด ์•ˆ์ข‹์€ ์Šต๊ด€.)
  return [...new Set(this)];
};

console.log(arr.unique()); // [3, 6, 5, 9]

Coding Challenge # 1

// Coding Challenge #1
// 1. Car'๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. 'Car'๋Š” 'make'์™€ 'speed' ์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 'speed' ์†์„ฑ์€ ์ž๋™์ฐจ์˜ ํ˜„์žฌ ์†๋„๋ฅผ km/h ๋‹จ์œ„๋กœ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
const Car = function (make, speed) {
  this.make = make;
  this.speed = speed;
};
// 2. 'accelerate' ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ์ž๋™์ฐจ์˜ ์†๋„๋ฅผ 10๋งŒํผ ์ฆ๊ฐ€์‹œํ‚ค๊ณ , ์ƒˆ๋กœ์šด ์†๋„๋ฅผ ์ฝ˜์†”์— ๋กœ๊ทธํ•ฉ๋‹ˆ๋‹ค.
const bmw = new Car(`BMW`, 120);
const mercedes = new Car(`Mercedes`, 95);
console.log(bmw, mercedes); // Car {make: 'BMW', speed: 120} Car {make: 'Mercedes', speed: 95}

Car.prototype.accelerate = function () { // accelerate method ๊ตฌํ˜„
  this.speed += 10;
  console.log(`${this.make} going at ${this.speed} km/h`);
};

// 3. 'brake' ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ์ž๋™์ฐจ์˜ ์†๋„๋ฅผ 5๋งŒํผ ๊ฐ์†Œ์‹œํ‚ค๊ณ , ์ƒˆ๋กœ์šด ์†๋„๋ฅผ ์ฝ˜์†”์— ๋กœ๊ทธํ•ฉ๋‹ˆ๋‹ค.

Car.prototype.brake = function () { // brake method ๊ตฌํ˜„
  this.speed -= 5;
  console.log(`${this.make} going at ${this.speed} km/h`);
};

// 4. 2๊ฐœ์˜ 'Car' ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ฐ๊ฐ์— ๋Œ€ํ•ด 'accelerate'์™€ 'brake'๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•ด๋ณด์„ธ์š”.
/* Test Data:
Data car 1: 'BMW' going at 120 km/h
Data car 2: 'Mercedes' going at 95 km/h */


bmw.accelerate(); // BMW going at 130 km/h
bmw.accelerate(); // BMW going at 140 km/h
bmw.brake(); // BMW going at 135 km/h
bmw.accelerate(); // BMW going at 145 km/h

mercedes.accelerate(); // Mercedes going at 105 km/h
mercedes.brake(); // Mercedes going at 100 km/h
mercedes.accelerate(); // Mercedes going at 110 km/h

ES6 Classes

// class  declaration
class PersonCl {
  constructor(firstName, birthYear) {
    this.firstName = firstName;
    this.birthYear = birthYear;
  }
  // Methods will be added to .prototype property
  calcAge() {
    console.log(2037 - this.birthYear);
  }

  greet() {
    console.log(`Hey ${this.firstName}`); // Hey Jessica
  }
}

const jessica = new PersonCl(`Jessica`, 1998);
console.log(jessica);
jessica.calcAge();
console.log(jessica.__proto__ === PersonCl.prototype); // true		

// PersonCl.prototype.greet = function () {
//   console.log(`Hey ${this.firstName}`);
// };
jessica.greet();

// 1. Classes are NOT hoisted
// 2. Classes are firtst-class citizes
// 3. Classes are executed in strict mode 

Setters and Getters

const account = {
  owner: `vancouver`,
  movements: [200, 530, 120, 300],

  get latest() {
    return this.movements.slice(-1).pop();
  },

  set latest(mov) {
    this.movements.push(mov);
  },
};
console.log(account.latest); //300

account.latest = 50;
console.log(account.movements); //  [200, 530, 120, 300, 50]

/////////////////////////////////////

class PersonCl {
  constructor(fullName, birthYear) {
    this.fullName = fullName;
    this.birthYear = birthYear;
  }
  // Methods will be added to .prototype property
  calcAge() {
    console.log(2037 - this.birthYear);
  }

  greet() {
    console.log(`Hey ${this.fullName}`);
  }

  get age() {
    return 2037 - this.birthYear;
  }
  // Set a property that already exists
  set fullName(name) {
    console.log(name); // Walter White Jessica Davis
    if (name.includes(` `)) this._fullName = name; // _fullName์˜ _๋Š” ๊ทœ์น™
    else alert(`${name} is not a full name!`);
  } //  fullName์ด ์•„๋‹๊ฒฝ์šฐ alert๊ฐ€ ์‹คํ–‰๋จ 

  get fullName() {
    return this._fullName;
 }
}

const walter = new PersonCl(`Walter White`, 1965);
const jessica = new PersonCl(`Jessica Davis`, 1998);

console.log(jessica);  //PersonCl {_fullName: 'Jessica Davis', birthYear: 1998}
console.log(jessica.age); // 39 

jessica.calcAge(); // 39
jessica.greet(); // Hey Jessica Davis
console.log(jessica.__proto__ === PersonCl.prototype); // true

Static Method (์ •์  ๋ฉ”์†Œ๋“œ)

Person.hey = function () {
  console.log(`Hey there ๐Ÿ–`); // Hey there ๐Ÿ–
};

Person.hey();



class PersonCl {
  .
  .
  .
  .
  //Static method
  static hey() {
    console.log(`Hey there ๐Ÿ–`); // Hey there ๐Ÿ–
    console.log(this); 
    /*class PersonCl {
  constructor(fullName, birthYear) {
    this.fullName = fullName;
    this.birthYear = birthYear;
  }
  // Methods will be added to .prototype property
  calcAge() {
    console.log(2037 โ€ฆ */
  }
}

PersonCl.hey();

Object.create()

const PersonProto = {
  calcAge() {
    console.log(2037 - this.birthYear);
  },

  init(firstName, birthYear) {
    this.firstName = firstName;
    this.birthYear = birthYear;
  },
};

const steven = Object.create(PersonProto);
console.log(steven); /*
birthYear: 2002
name: "Steven"
[[Prototype]]: Object*/
steven.name = `Steven`;
steven.birthYear = 2002;
steven.calcAge(); // 35

console.log(steven.__proto__ === PersonProto);

const sarah = Object.create(PersonProto);
sarah.init(`Sarah`, 1979);
sarah.calcAge(); // 58

Coding Challenge #2

// Coding Challenge #2

// 1.ES6 ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Challenge #1์„ ๋‹ค์‹œ ์ƒ์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค์˜ ์ด๋ฆ„์€ 'CarCl'๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

// 2.'speedUS'๋ผ๋Š” getter๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํ˜„์žฌ ์†๋„๋ฅผ mi/h ๋‹จ์œ„๋กœ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. (์ž…๋ ฅ๋œ ์†๋„๋ฅผ 1.6์œผ๋กœ ๋‚˜๋ˆ•๋‹ˆ๋‹ค.)

// 3.'speedUS'๋ผ๋Š” setter๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํ˜„์žฌ ์†๋„๋ฅผ mi/h ๋‹จ์œ„๋กœ ์„ค์ •ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. (์ž…๋ ฅ๋œ ์†๋„๋ฅผ 1.6์œผ๋กœ ๊ณฑํ•œ ํ›„ ๊ฐ’์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.)

// 4. ์ƒˆ๋กœ์šด ์ž๋™์ฐจ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  'accelerate'์™€ 'brake' ๋ฉ”์„œ๋“œ, ๊ทธ๋ฆฌ๊ณ  getter์™€ setter๋ฅผ ์‹คํ—˜ํ•ด๋ณด์„ธ์š”.

// Test data:
// Data car 1: 'Ford' going at 120 km/h

class CarCl {
  constructor(make, speed) {
    this.make = make;
    this.speed = speed;
  }
  accelerate = function () {
    this.speed += 10;
    console.log(`${this.make} going at ${this.speed} km/h`);
  };
  brake = function () {
    this.speed -= 5;
    console.log(`${this.make} going at ${this.speed} km/h`);
  };
  get speedUS() {
    return this.speed / 1.6;
  }

  set speedUS(speed) {
    console.log(`${this.make} going at ${(this.speed = speed * 1.6)} mi/h`); // Ford going at 80 mi/h
  }
}

const ford = new CarCl(`Ford`, 120);


console.log(ford.speedUS);
ford.accelerate(); // Ford going at 130 km/h
ford.brake(); // Ford going at 125 km/h
ford.speedUS = 120;
console.log(ford); // CarCl {make: 'Ford', speed: 192, accelerate: ฦ’, brake: ฦ’}
// console.log(ford.speed);

Inheritance Between "Classes": Constructor Functions ("ํด๋ž˜์Šค" ๊ฐ„์˜ ์ƒ์†: ์ƒ์„ฑ์ž ํ•จ์ˆ˜)




Student.prototype = Object.create(Person.prototype); // class๊ฐ„์˜ ์—ฐ๊ฒฐ
const Person = function (firstName, birthYear) {
  // Instance properties
  this.firstName = firstName;
  this.birthYear = birthYear;

  // Never to this (์ ˆ๋Œ€ ์ด๋Ÿฐ์‹์œผ๋กœ ๋งŒ๋“ค๋ฉด ์•ˆ๋จ)
  //   this.calcAge = function () {
  //     console.log(2037 - this.birthYear);
  //   };
};

Person.prototype.calcAge = function () {
  console.log(2037 - this.birthYear);
};

const Student = function (firstName, birthYear, course) {
  // this.firstName = firstName;
  // this.birthYear = birthYear;
  // this.course = course;
  Person.call(this, firstName, birthYear);
  this.course = course;
};

//****์ค‘ (Linking prototypes) ์š”****
Student.prototype = Object.create(Person.prototype);

Student.prototype.introduce = function () {
  console.log(`My name is ${this.firstName} and i study ${this.course}`);
};

const mike = new Student(`Mike`, 2020, `Computer Science`);
mike.introduce(); // My name is Mike and i study Computer Science
mike.calcAge(); // 17

console.log(mike.__proto__);
console.log(mike.__proto__.__proto__);

console.log(mike instanceof Student); // true
console.log(mike instanceof Person); // true
console.log(mike instanceof Object); // true

Student.prototype.constructor = Student;
console.dir(Student.prototype.constructor);

Coding Challenge #3

// Coding Challenge #3

// 1. 'EV' ์ž์‹ ํด๋ž˜์Šค๋กœ 'Car'์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ „๊ธฐ ์ž๋™์ฐจ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. 'EV'๋Š” ์ œ์กฐ์‚ฌ์™€ ํ˜„์žฌ ์†๋„ ์™ธ์—๋„ ๋ฐฐํ„ฐ๋ฆฌ ์ถฉ์ „ ์ƒํƒœ๋ฅผ ํผ์„ผํŠธ๋กœ ๋‚˜ํƒ€๋‚ด๋Š” 'charge' ์†์„ฑ์„ ๊ฐ–์Šต๋‹ˆ๋‹ค
const EV = function (make, speed, charge) {
  Car.call(this, make, speed);
  this.charge = charge;
};

EV.prototype = Object.create(Car.prototype);
// 2. 'chargeBattery' ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์†Œ๋“œ๋Š” 'chargeTo'๋ผ๋Š” ์ธ์ž๋ฅผ ๋ฐ›์•„์„œ ๋ฐฐํ„ฐ๋ฆฌ ์ถฉ์ „ ์ƒํƒœ๋ฅผ 'chargeTo'๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
EV.prototype.chargeBattery = function (chargeTo) {
  this.charge = chargeTo;
  console.log(this.charge);
};
// 3. 'accelerate' ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์†Œ๋“œ๋Š” ์ž๋™์ฐจ์˜ ์†๋„๋ฅผ 20๋งŒํผ ์ฆ๊ฐ€์‹œํ‚ค๊ณ  ์ถฉ์ „ ์ƒํƒœ๋ฅผ 1% ๊ฐ์†Œ์‹œํ‚ต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค:
// 'Tesla๊ฐ€ 140 km/h๋กœ ์ฃผํ–‰ ์ค‘์ด๋ฉฐ ์ถฉ์ „ ์ƒํƒœ๋Š” 22%์ž…๋‹ˆ๋‹ค.'

const tesla = new EV(`Tesla`, 120, 23);

EV.prototype.accelerate = function () {
  this.speed += 20;
  this.charge--;

  console.log(
    `${this.make} going at ${this.speed}km/h, with a charge of ${this.charge}%`
  );
};

// 4. ์ „๊ธฐ ์ž๋™์ฐจ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  'accelerate', 'brake', 'chargeBattery'๋ฅผ ํ˜ธ์ถœํ•ด ๋ณด์„ธ์š”. 'accelerate'๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ์ฃผ๋ชฉํ•˜์„ธ์š”!
// ํžŒํŠธ: ๋‹คํ˜•์„ฑ(polymorphism)์˜ ์ •์˜๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•˜์„ธ์š”.

// Test data:
// Data car 1: 'Tesla' going at 120 km/h, with a charge of 23%

tesla.accelerate(); // Tesla going at 140km/h, with a charge of 22%
tesla.accelerate(); // Tesla going at 160km/h, with a charge of 21%
tesla.brake(); // Tesla going at 155 km/h
tesla.chargeBattery(90); // 90

Inheritance Between "Classes": ES6 Classes ("ํด๋ž˜์Šค" ๊ฐ„์˜ ์ƒ์†: ES6 ํด๋ž˜์Šค)

class studentCl extends PersonCl {
  constructor(fullName, birthYear, course) {
    // Always needs to happen first!
    super(fullName, birthYear);
    this.course = course;
  }
  // extends๋ฅผ ์ด์šฉํ•˜์—ฌ ํด๋ž˜์Šค๊ฐ„์˜ ์ƒ์†์„ ์ด์–ด๋ฐ›์Œ.

class๊ฐ„์˜ ์šฐ์„ ์ˆœ์œ„

class PersonCl {
  calcAge() {
    console.log(2037 - this.birthYear);
  }
}
// studentCl์˜ calcAge() method๊ฐ€ ์šฐ์„ ์ˆœ์œ„์— ์žˆ์Œ. (๋ฎ์–ด ์“ธ์ˆ˜์žˆ๋‹ค.)
class studentCl {
  calcAge() {
    console.log(
      `I'm ${2037 - this.birthYear} years old, but a student I feel more like ${2037 - this.birthYear + 10}`);
   }
}
// class  declaration
class PersonCl {
  constructor(fullName, birthYear) {
    this.fullName = fullName;
    this.birthYear = birthYear;
  }
  // Methods will be added to .prototype property
  calcAge() {
    console.log(2037 - this.birthYear);
  }

  greet() {
    console.log(`Hey ${this.fullName}`);
  }

  get age() {
    return 2037 - this.birthYear;
  }
  // Set a property that already exists
  set fullName(name) {
    console.log(name); // Walter White Jessica Davis
    if (name.includes(` `)) this._fullName = name;
    else alert(`${name} is not a full name!`);
  }

  get fullName() {
    return this._fullName;
  }

  //Static method
  static hey() {
    console.log(`Hey there ๐Ÿ–`);
    console.log(this);
  }
}
class studentCl extends PersonCl {
  constructor(fullName, birthYear, course) {
    // Always needs to happen first!
    super(fullName, birthYear);
    this.course = course;
  }

  introduce() {
    console.log(`My name is ${this.fullName} and i study ${this.course}`);
  }

  calcAge() {
    console.log(
      `I'm ${2037 - this.birthYear} years old, but a student I feel more like ${
        2037 - this.birthYear + 10
      }`
    );
  }
}
const martha = new studentCl(`Martha Jones`, 2012, `Computer Science`);
martha.introduce(); // My name is Martha Jones and i study Computer Science
martha.calcAge(); // I'm 25 years old, but a student I feel more like 35

Inheritance Between "Classes": Object.create ("ํด๋ž˜์Šค" ๊ฐ„์˜ ์ƒ์†: Object.create)

const PersonProto = {
  calcAge() {
    console.log(2037 - this.birthYear);
  },

  init(firstName, birthYear) {
    this.firstName = firstName;
    this.birthYear = birthYear;
  },
};

const StudentProto = Object.create(PersonProto); // KeyPoint
const jay = Object.create(StudentProto); // KeyPoint

StudentProto.init = function (firstName, birthYear, course) {
  PersonProto.init.call(this, firstName, birthYear);
  this.course = course;
};
StudentProto.introduce = function () {
  console.log(`My name is ${this.firstName} and i study ${this.course}`);
};


jay.init(`Jay`, 2010, `Computer Science`);
jay.introduce(); // My name is Jay and i study Computer Science
jay.calcAge(); // 27

Another Class Example

class Account {
  constructor(owner, currency, pin) {
    this.owner = owner;
    this.currency = currency;
    this.pin = pin;
    this.movements = [];
    this.locale = navigator.language;
    console.log(`Thanks for opening an account, ${owner}`); // Thanks for opening an account, vancouver
  }
  deposit(val) {
    this.movements.push(val);
  }
  withdraw(val) {
    this.deposit(-val);
  }

  approveLoan(val) {
    return true;
  }

  requestLoan(val) {
    if (this.approveLoan(val)) {
      this.deposit(val);
      console.log(`Loan approved`);
    }
  }
}

// Public interface
const acc1 = new Account(`vancouver`, `EUR`, 1111);

// acc1.movements.push(250);
// acc1.movements.push(-140);
acc1.deposit(250);
acc1.withdraw(140);
acc1.requestLoan(1000); // Loan approved
acc1.approveLoan(1000); // approveLoan method์˜ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์–ด์•ผ ํ•จ.

console.log(acc1);/* 
Account {owner: 'vancouver', currency: 'EUR', pin: 1111, movements: Array(3), locale: 'ko-KR'}
currency: "EUR"
locale: "ko-KR"
movements: (3) [250, -140, 1000]
owner: "vancouver"
pin: 1111
[[Prototype]]: Object */
console.log(acc1.pin); // 1111

Encapsulation: Protected Properties and Methods, Private Class Fields and Methods ์บก์Šํ™”: (๋ณดํ˜ธ๋œ ์†์„ฑ ๋ฐ ๋ฉ”์„œ๋“œ, ๊ฐœ์ธ ํด๋ž˜์Šค ํ•„๋“œ ๋ฐ ๋ฉ”์„œ๋“œ)

class Account {
  // 1) Public fields (instances)
  locale = navigator.language;

  // 2) Private fields (instances)
  #movements = [];
  #pin;

  constructor(owner, currency, pin) {
    this.owner = owner;
    this.currency = currency;
    // Protected property
    this.#pin = pin;
    // this._movements = [];
    // this.locale = navigator.language;
    console.log(`Thanks for opening an account, ${owner}`); // Thanks for opening an account, vancouver
  }
  // 3) Public methods

  // Public interface
  getmovements() {
    return this.#movements;
  }

  deposit(val) {
    this.#movements.push(val);
  }
  withdraw(val) {
    this.deposit(-val);
  }

  requestLoan(val) {
    // if (this.#approveLoan(val)) {
    if (this._approveLoan(val)) {
      this.deposit(val);
      console.log(`Loan approved`);
    }
  }
  // 4) Private methods

  // #approveLoan(val) {
  _approveLoan(val) {
    return true;
  }
}

// Public interface
const acc1 = new Account(`vancouver`, `EUR`, 1111);

// acc1._movements.push(250);
// acc1._movements.push(-140);
acc1.deposit(250);
acc1.withdraw(140);
acc1.requestLoan(1000); // Loan approved
acc1._approveLoan(1000); // approveLoan method์˜ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์–ด์•ผ ํ•จ.
console.log(acc1.getmovements());

console.log(acc1); /* 
Account {owner: 'vancouver', currency: 'EUR', pin: 1111, movements: Array(3), locale: 'ko-KR'}
currency: "EUR"
locale: "ko-KR"
movements: (3) [250, -140, 1000]
owner: "vancouver"
pin: 1111
[[Prototype]]: Object */
console.log(acc1.pin); // 1111

// console.log(acc1.#movements);
// Uncaught SyntaxError: Private field '#movements' must be declared in an enclosing class๋ผ๋Š” ์˜ค๋ฅ˜๊ฐ€ ์ƒ๊น€
// console.log(acc1.#pin);
// ์ดํ•˜๋™๋ฌธ

Chaining methods

// Chaining
acc1.deposit(300).deposit(500).withdraw(35).requestLoan(25000).withdraw(4000);
// Account ํด๋ž˜์Šค์•ˆ์— ์žˆ๋Š” ๊ฐ์ฒด์˜ return์„ ์•ˆ๊ฑธ์–ด์ฃผ๋ฉด TypeError๊ฐ€ ๋ฐœ์ƒ
 getmovements() {
    return this.#movements; // return์„ ๊ฑธ์–ด์ค˜์•ผํ•จ.
  }

  deposit(val) {
    this.#movements.push(val);
    return this;
  }
  withdraw(val) {
    this.deposit(-val);
    return this;
  }

  requestLoan(val) {
    // if (this.#approveLoan(val)) {
    if (this._approveLoan(val)) {
      this.deposit(val);
      console.log(`Loan approved`);
      return this;
    }
  }
  // 4) Private methods

  // #approveLoan(val) {
  _approveLoan(val) {
    return true;
  }
}
console.log(acc1.getmovements()); //  [250, -140, 1000, 300, 500, -35, 25000, -4000]

ES6 Classes Summary

class Student extends Person 
// Student: Child class 
// Person: Parent class 
// extends: ํด๋ž˜์Šค ๊ฐ„ ์ƒ์†, ์ž๋™์œผ๋กœ ํ”„๋กœํ† ํƒ€์ž… ์„ค์ •

์ƒ์„ฑ์ž ๋ฉ”์„œ๋“œ(Constructor method)๋Š” new ์—ฐ์‚ฐ์ž์— ์˜ํ•ด ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ์ผ๋ฐ˜ ํด๋ž˜์Šค์—์„œ๋Š” ํ•„์ˆ˜์ ์œผ๋กœ ์ •์˜๋˜์–ด์•ผ ํ•˜์ง€๋งŒ, ์ž์‹ ํด๋ž˜์Šค์—์„œ๋Š” ์ถ”๊ฐ€์ ์ธ ์ดˆ๊ธฐํ™” ์ž‘์—…์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋Š” ์ƒ๋žต๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

constructor(fullName, birthYear, startYear) { 
}

๊ณต๊ฐœ ํ•„๋“œ(์†์„ฑ๊ณผ ์œ ์‚ฌ, ์ƒ์„ฑ๋œ ๊ฐœ์ฒด์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ)

 university = `University of Lishon`

๋น„๊ณต๊ฐœ ํ•„๋“œ(ํด๋ž˜์Šค ์™ธ๋ถ€์—์„œ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†์Œ)

#studyHours = 0;
#course

์ •์  ๊ณต๊ฐœ ํ•„๋“œ(ํด๋ž˜์Šค์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ)

static numSubjects = 10;

์ƒ์œ„(์Šˆํผ) ํด๋ž˜์Šค๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค(ํ™•์žฅ์— ํ•„์š”). ์•ก์„ธ์Šคํ•˜๊ธฐ ์ „์— ๋ฐœ์ƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

super (fullName, birthYear)

์ธ์Šคํ„ด์Šค ์†์„ฑ(์ƒ์„ฑ๋œ ๊ฐ์ฒด์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

this.startYear = startYear

ํ”„๋ผ์ด๋น— ํ•„๋“œ ์žฌ์ •์˜

this.#course = this.#course

Public method

introduce() {
       console.log(`I study ${this.#course} at ${this.university}`);
   }

๊ฐœ์ธ ํ•„๋“œ ๋ฐ ๋ฉ”์†Œ๋“œ ์ฐธ์กฐ

 study(h){
        this.#makeCoffe()
this.#studyHours += h
 }

Private method (โš  ์•„์ง ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.๋ธŒ๋ผ์šฐ์ €. "๊ฐ€์งœ" ๋Œ€์•ˆ: _ ๋Œ€์‹  #)

#makeCoffe(){
        return `Here is a coffe for you`
    }

getter method

get testScore(){
        return this._testScore
    }

setter method ( _ ์†์„ฑ์„ ์„ค์ •ํ•˜๋ ค๋ฉด ๋ฉ”์†Œ๋“œ์™€ ๊ฐ™์€ ์ด๋ฆ„ ์‚ฌ์šฉ, getter๋„ ์ถ”๊ฐ€)

 set testScore(score){
        this._testScore = score <= 20 ? score:0;
    }

static method (ํด๋ž˜์Šค์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ. ์ธ์Šคํ„ด์Šค ์†์„ฑ์ด๋‚˜ ๋ฉ”์„œ๋“œ, ์ •์  ์†์„ฑ๋งŒ ํ•ด๋‹น ์ ‘๊ทผ ๋ถˆ๊ฐ€)

static printCurriculum(){
        console.log(`There are ${this.numSubjects} subjects`);
    }

new ์—ฐ์‚ฐ์ž๋กœ ์ƒˆ ๊ฐ์ฒด ์ƒ์„ฑ

const student = new Student(`vancouver`, 2020, 2037, `Computer Science`)

์ฐธ๊ณ 

  1. ํด๋ž˜์Šค๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์œ„์— ๋ง๋ถ™์—ฌ์ง„ "๋ฌธ๋ฒ•์  ์„คํƒ•(syntactic sugar)"์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๋ฉด ์‹ค์ œ๋กœ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑ๋˜์–ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€๋งŒ ๋” ๊ฐ„๊ฒฐํ•˜๊ณ  ๋ช…ํ™•ํ•œ ๋ฌธ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  2. ํด๋ž˜์Šค๋Š” ํ˜ธ์ด์ŠคํŒ…๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค ์ •์˜๋Š” ์‹คํ–‰ ํ๋ฆ„์— ๋”ฐ๋ผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ง„ํ–‰๋˜๋ฉฐ, ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ์ •์˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  3. ํด๋ž˜์Šค๋Š” ์ผ๊ธ‰ ์‹œ๋ฏผ(first-class citizens)์ž…๋‹ˆ๋‹ค. ์ด๋Š” ํด๋ž˜์Šค๋ฅผ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•˜๊ฑฐ๋‚˜, ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜, ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ํด๋ž˜์Šค๋Š” ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ธฐ๋ณธ ์›์น™์„ ์ง€์›ํ•˜๋ฉฐ, ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ์œ ํ˜•๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  4. ํด๋ž˜์Šค์˜ ๋ณธ๋ฌธ์€ ํ•ญ์ƒ strict mode(์—„๊ฒฉ ๋ชจ๋“œ)์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํด๋ž˜์Šค ๋‚ด์—์„œ ์ž๋™์œผ๋กœ ์—„๊ฒฉ ๋ชจ๋“œ๊ฐ€ ์ ์šฉ๋˜์–ด ๋ณ€์ˆ˜ ์„ ์–ธ์ด๋‚˜ ํ•จ์ˆ˜ ์‚ฌ์šฉ ๋“ฑ์— ์—„๊ฒฉํ•œ ๊ทœ์น™์ด ์ ์šฉ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

class Student extends Person {
    university = `University of Lishon`
    #studyHours = 0;
    #course
    static numSubjects = 10;

    constructor(fullName, birthYear, startYear) {
        super (fullName, birthYear);

        this.startYear = startYear
        this.#course = this.#course
    }

    introduce() {
        console.log(`I study ${this.#course} at ${this.university}`);
    }
    study(h){
        this.#makeCoffe()
this.#studyHours += h
    }
    #makeCoffe(){
        return `Here is a coffe for you`
    }
    get testScore(){
        return this._tesScore
    }
    set testScore(score){
        this._testScore = score <= 20 ? score:0;
    }

    static printCurriculum(){
        console.log(`There are ${this.numSubjects} subjects`);
    }
}
const student = new Student(`vancouver`, 2020, 2037, `Computer Science`)

Coding Challenge #4

// Coding Challenge #4

// 1. ์ฑŒ๋ฆฐ์ง€ #3์„ ๋‹ค์‹œ ๋งŒ๋“ค์ง€๋งŒ, ์ด๋ฒˆ์—๋Š” ES6 ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ: 'CarCl' ํด๋ž˜์Šค์˜ 'EVCl' ์–ด๋ฆฐ์ด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค

// 2. '์ฒญ๊ตฌ' ์†์„ฑ์„ ๋น„๊ณต๊ฐœ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค

// 3. ์ด ํด๋ž˜์Šค์˜ '๊ฐ€์†' ๋ฐ '๋ฐฐํ„ฐ๋ฆฌ ์ถฉ์ „' ๋ฉ”์„œ๋“œ๋ฅผ ์ฒด์ธ์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ณ , 'CarCl' ํด๋ž˜์Šค์˜ '๋ธŒ๋ ˆ์ดํฌ' ๋ฉ”์„œ๋“œ๋„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ฒด์ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹คํ—˜ํ•ฉ๋‹ˆ๋‹ค

class CarCl {
  constructor(make, speed) {
    this.make = make;
    this.speed = speed;
  }
  accelerate() {
    this.speed += 10;
    console.log(`${this.make} going at ${this.speed} km/h`);
  }
  brake() {
    this.speed -= 5;
    console.log(`${this.make} going at ${this.speed} km/h`);
    return this;
  }
  get speedUS() {
    return this.speed / 1.6;
  }

  set speedUS(speed) {
    console.log(`${this.make} going at ${(this.speed = speed * 1.6)} mi/h`);
  }
}

class EVCl extends CarCl {
  #charge;

  constructor(make, speed, charge) {
    super(make, speed);
    this.#charge = charge;
  }

  chargeBattery(chargeTo) {
    this.#charge = chargeTo;
    return this;
  }

  accelerate() {
    this.speed += 20;
    this.#charge--;

    console.log(
      `${this.make} going at ${this.speed}km/h, with a charge of ${
        this.#charge
      }%`
    );
    return this;
  }
}

 const rivian = new EVCl(`Rivian`, 120, 23);
 console.log(rivian);
// console.log(rivian.#charge);
rivian.accelerate().accelerate().chargeBattery(50).accelerate().brake();
// Rivian going at 140km/h, with a charge of 22%
// Rivian going at 160km/h, with a charge of 21%
// Rivian going at 180km/h, with a charge of 49%
// Rivian going at 175 km/h
console.log(rivian.speedUS);
// 109.375

0๊ฐœ์˜ ๋Œ“๊ธ€