From 14db2f204cc8a5b29fd121315a566023d97b6e8c Mon Sep 17 00:00:00 2001 From: Dmytro Date: Wed, 10 Mar 2021 18:34:22 +0200 Subject: [PATCH 1/6] First version of done homework. --- HW5(OOP_vs_FP)/HW5_Khyzhniak.js | 333 ++++++++++++++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 HW5(OOP_vs_FP)/HW5_Khyzhniak.js diff --git a/HW5(OOP_vs_FP)/HW5_Khyzhniak.js b/HW5(OOP_vs_FP)/HW5_Khyzhniak.js new file mode 100644 index 0000000..b85c384 --- /dev/null +++ b/HW5(OOP_vs_FP)/HW5_Khyzhniak.js @@ -0,0 +1,333 @@ +// 1. Iterative style +log('--- TASK #1 | IMPERATIVE STYLE ---'); + +function imperativeStyle() { + // We have an array containing the year of birth of some people, and we need to create an array that will contain their age in 2020 + const birthDates = [2001, 2000, 1992, 1969, 2010]; + const howOldIn2020 = []; + + for (let i = 0; i < birthDates.length; i++) { + howOldIn2020.push(2020 - birthDates[i]); + } + console.log(howOldIn2020); // [19, 20, 28, 51, 10] + + // We have an array containing objects, the properties of which store information about the name and age of representatives of a certain group of people. + // We need to create an array, which will contain information only about the adult representatives of this group (those whose age has reached 18 years old) + const groupOfPeople = [ + { name: 'Dmytro', age: 19}, + { name: 'Andrew', age: 21}, + { name: 'John', age: 5}, + { name: 'Kate', age: 15}, + { name: 'Matthew', age: 60}, + ]; + + const adultGroupOfPeople = []; + + for (let i = 0; i < groupOfPeople.length; i++) { + if (groupOfPeople[i].age >= 18) adultGroupOfPeople.push(groupOfPeople[i]); + } + + console.log(adultGroupOfPeople); // [{ name: 'Dmytro', age: 19}, { name: 'Andrew', age: 21}, { name: 'Matthew', age: 60}] + + // Let's say we have an array of numbers. We need to calculate the sum of its elements. + const someNumbers = [10, 20, 30, 50, 100]; + let sum = 0; + + for (let i = 0; i < someNumbers.length; i++) { + sum += someNumbers[i]; + } + + console.log(sum); // 210 + + // Let's say JavaScript doesn't have a standard array method map(). + // We can easily create such a method on our own, which will be expressed in the development of a higher-order function + + // Suppose we have an array of strings, and we would like to create an array with numbers on its basis, + // each of which represents the length of a string stored in some element of the original array. + + const getLength = str => str.length; // callback for our map; + const someStrings = ['hi', 'yup', 'form', 'random', 'x']; // array of strings + + someStrings.customMap = function (callback) { + const result = []; + + for (let i = 0; i < this.length; i++) { + result.push(callback(this[i])); + } + + return result; + } + + console.log(someStrings.customMap(getLength)); // [2, 3, 4, 6, 1] +} +imperativeStyle(); + +// 2. Applying higher-order functions +log('--- TASK #1 | DECLARATIVE STYLE ---'); + +function declarativeStyle() { + // We have an array containing the year of birth of some people, and we need to create an array that will contain their age in 2020 + const birthDates = [2001, 2000, 1992, 1969, 2010]; + + const howOldIn2020 = birthDates.map(yearOfBirth => 2020 - yearOfBirth); + console.log(howOldIn2020) // [19, 20, 28, 51, 10] + + // We have an array containing objects, the properties of which store information about the name and age of representatives of a certain group of people. + // We need to create an array, which will contain information only about the adult representatives of this group (those whose age has reached 18 years old) + const groupOfPeople = [ + { name: 'Dmytro', age: 19}, + { name: 'Andrew', age: 21}, + { name: 'John', age: 5}, + { name: 'Kate', age: 15}, + { name: 'Matthew', age: 60}, + ]; + + const adultGroupOfPeople = groupOfPeople.filter(person => person.age >= 18); + console.log(adultGroupOfPeople); // [{ name: 'Dmytro', age: 19}, { name: 'Andrew', age: 21}, { name: 'Matthew', age: 60}] + + // Let's say we have an array of numbers. We need to calculate the sum of its elements. + const someNumbers = [10, 20, 30, 50, 100]; + let sum = someNumbers.reduce((sum, num) => sum + num); + console.log(sum); // 210 + + // Suppose we have an array of strings, and we would like to create an array with numbers on its basis, + // each of which represents the length of a string stored in some element of the original array. + + const someStrings = ['hi', 'yup', 'form', 'random', 'x']; + const lengthsOfStrings = someStrings.map(str => str.length); + console.log(lengthsOfStrings); // [2, 3, 4, 6, 1] +} +declarativeStyle(); + +log('--- TASK #2 ---'); +// The implementation and usefulness of ideas should be clearly demonstrated: Inheritance, encapsulation, polymorphism (as much as possible) +// Implement in two ways. With the help of the ES6 classes and with the help of prototypes. + +log('--- TASK #2 | Classes ---'); +function newScopeForTask2() { + // Write an abstract class + class User { + constructor(nickname) { + this.nickname = nickname ?? 'Guest'; + this.id = null; + this.avatar = null; + this.canWrite = null; + this.isLogged = null; + this.isAdmin = null; + } + + login = function() {}; + logout = function() {}; + writeInChat = function() {}; // Polymorphism* + } + + // Create two classes using inheritance (not abstract) + class Guest extends User { // Inheritance + constructor(nickname) { + super(nickname); + + this.isLogged = false; + this.canWrite = false; + } + } + + class RegistredUser extends Guest { // Inheritance + constructor(nickname) { + super(nickname); + + this.id = 'some id'; + this.avatar = 'some avatar'; + this.canWrite = true; + this.isLogged = false; + this.isAdmin = false; + } + + login = function() { + this.isLogged = true; + }; + + logout = function() { + this.isLogged = false; + }; + + writeInChat = function(text) { // Polymorphism* + console.log(text); + }; + } + + class Administrator extends RegistredUser { // Inheritance + constructor(nickname) { + super(nickname); + + this.canWrite = true; + this.isAdmin = true; + } + + writeInChat = function(text) { // Polymorphism* + alert(`*** ADMIN ***: ${text}`); + }; + + deleteMessages = function(id) { + console.log(`Deleted message #${id}`); + } + } + + // Create instances of these classes + const visitor = new Guest(); + console.log(visitor); + + const user = new RegistredUser('Anthony'); + console.log(user); + + const adminDmytro = new Administrator('Dmytro'); + console.log(adminDmytro); +} +newScopeForTask2(); + +/* + INCAPS - get, set +*/ + +log('--- TASK #2 | Prototypes ---'); +// Write an abstract class +function User() { + this.nickname = null; + this.id = null; + this.avatar = null; + this.canWrite = null; + this.isLogged = null; + this.isAdmin = null; +} + User.prototype.login = function() {}; + User.prototype.logout = function() {}; + User.prototype.writeInChat = function() {}; // Polymorphism* + +// Create two classes using inheritance (not abstract) +function Guest() { + User.call(this); // Inheritance + + this.nickname = 'Guest'; + this.isLogged = false; + this.canWrite = false; +} + +function RegistredUser(nickname) { + Guest.call(this); // Inheritance + + this.nickname = nickname; + this.id = 'some id'; + this.avatar = 'some avatar'; + this.canWrite = true; + this.isLogged = false; + this.isAdmin = false; +} + RegistredUser.prototype.login = function() { + this.isLogged = true; + }; + RegistredUser.prototype.logout = function() { + this.isLogged = false; + }; + RegistredUser.prototype.writeInChat = function(text) { + console.log(text); + }; + +function Administrator(nickname) { + RegistredUser.call(this, nickname); // Inheritance + + this.canWrite = true; + this.isAdmin = true; +} + Administrator.prototype.writeInChat = function(text) { // Polymorphism* + alert(`*** ADMIN ***: ${text}`); + }; + Administrator.prototype.deleteMessages = function(id) { + console.log(`Deleted message #${id}`); + } + +// Create instances of these classes +const visitor = new Guest(); +console.log(visitor); + +const user = new RegistredUser('Anthony'); +console.log(user); + +const adminDmytro = new Administrator('Dmytro'); +console.log(adminDmytro); + +// 3. Come up with and write an example program that will contain and demonstrate the principle of operation. +log('--- TASK #3 ---'); +// Higher-order functions +const info = [ +{ name: 'Dmytro', age: 19}, +{ name: 'Andrew', age: 21}, +{ name: 'John', age: 5}, +{ name: 'Kate', age: 15}, +{ name: 'Matthew', age: 60} +].map(person => `${person.name} is ${person.age} years old.`); // .map() is one of HOF + +// First class functions +const getFullName = function(firstName, lastName) { // Means that we can assign functions to a variables + return `${firstName} ${lastName}`; +} +console.log(getFullName('Dmytro', 'Khyzhniak')); // 'Dmytro Khyzhniak' + +// Pure functions +function strHider(str) { + return str.replace(/\w/g, '*'); +} +strHider('Dmytro'); + +// Function side effect +const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + +function getHalf(arr) { + return arr.splice(0, arr.length / 2); +} +getHalf(numbers); + +console.log(numbers); // [6, 7, 8, 9, 10] | Our array was changed with splice() + +// Unchanging state +let userName = 'Dmytro'; +userName[0] = 'X'; + +console.log(userName); // 'Dmytro' | Immutable + +let newUserName = 'X' + userName.slice(1); +console.log(newUserName); // Xmytro | We can copy only + +// Shared State +let counter = 10; + +const func1 = () => counter++; +const func2 = () => ++counter; + +func1(); +func2(); + +console.log(counter); // 12 | Both functions are working with the same counter + +// Closures +function pow(base) { + return function(exp) { + return base ** exp; + } +} + +console.log(pow(2)(2)) // 4 +// Recursion +function getSum(num) { + return num <= 0 ? num : num + getSum(num - 1); +} + +console.log(getSum(10)); // 55 | 10 + 9 + 8 ... + +// Partial function application +const MathPow = (base, exp) => base ** exp; + +const powOfSeven = MathPow.bind(null, 7); +console.log(powOfSeven(2)); // 49 + +function log(text) { + console.log(`%c ${text} `, 'color: green; font-weight: bold; font-size: 1.5em;'); +} \ No newline at end of file From 6efb1826dc15c03c7b3af4304ec60c1fccd60131 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Thu, 11 Mar 2021 18:59:19 +0200 Subject: [PATCH 2/6] Improved classes --- HW5(OOP_vs_FP)/HW5_Khyzhniak.js | 35 +++++++++++++++++---------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/HW5(OOP_vs_FP)/HW5_Khyzhniak.js b/HW5(OOP_vs_FP)/HW5_Khyzhniak.js index b85c384..0a3a959 100644 --- a/HW5(OOP_vs_FP)/HW5_Khyzhniak.js +++ b/HW5(OOP_vs_FP)/HW5_Khyzhniak.js @@ -107,13 +107,14 @@ log('--- TASK #2 | Classes ---'); function newScopeForTask2() { // Write an abstract class class User { + id = null; + avatar = null; + canWrite = null; + isLogged = null; + isAdmin = null; + constructor(nickname) { this.nickname = nickname ?? 'Guest'; - this.id = null; - this.avatar = null; - this.canWrite = null; - this.isLogged = null; - this.isAdmin = null; } login = function() {}; @@ -123,23 +124,23 @@ function newScopeForTask2() { // Create two classes using inheritance (not abstract) class Guest extends User { // Inheritance + isLogged = false; + canWrite = false; + constructor(nickname) { super(nickname); - - this.isLogged = false; - this.canWrite = false; } } class RegistredUser extends Guest { // Inheritance + id = 'some id'; + avatar = 'some avatar'; + canWrite = true; + isLogged = false; + isAdmin = false; + constructor(nickname) { super(nickname); - - this.id = 'some id'; - this.avatar = 'some avatar'; - this.canWrite = true; - this.isLogged = false; - this.isAdmin = false; } login = function() { @@ -156,11 +157,11 @@ function newScopeForTask2() { } class Administrator extends RegistredUser { // Inheritance + canWrite = true; + isAdmin = true; + constructor(nickname) { super(nickname); - - this.canWrite = true; - this.isAdmin = true; } writeInChat = function(text) { // Polymorphism* From e2a2f67f9a705687188d9a70810f4313f586a4b8 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Thu, 11 Mar 2021 21:59:38 +0200 Subject: [PATCH 3/6] Encapsulation example was added + some improvements. --- HW5(OOP_vs_FP)/HW5_Khyzhniak.js | 89 +++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/HW5(OOP_vs_FP)/HW5_Khyzhniak.js b/HW5(OOP_vs_FP)/HW5_Khyzhniak.js index 0a3a959..bc79567 100644 --- a/HW5(OOP_vs_FP)/HW5_Khyzhniak.js +++ b/HW5(OOP_vs_FP)/HW5_Khyzhniak.js @@ -1,7 +1,7 @@ // 1. Iterative style log('--- TASK #1 | IMPERATIVE STYLE ---'); -function imperativeStyle() { +function imperativeStyleExample() { // We have an array containing the year of birth of some people, and we need to create an array that will contain their age in 2020 const birthDates = [2001, 2000, 1992, 1969, 2010]; const howOldIn2020 = []; @@ -21,13 +21,13 @@ function imperativeStyle() { { name: 'Matthew', age: 60}, ]; - const adultGroupOfPeople = []; + const adultPartOfGroup = []; for (let i = 0; i < groupOfPeople.length; i++) { - if (groupOfPeople[i].age >= 18) adultGroupOfPeople.push(groupOfPeople[i]); + if (groupOfPeople[i].age >= 18) adultPartOfGroup.push(groupOfPeople[i]); } - console.log(adultGroupOfPeople); // [{ name: 'Dmytro', age: 19}, { name: 'Andrew', age: 21}, { name: 'Matthew', age: 60}] + console.log(adultPartOfGroup); // [{ name: 'Dmytro', age: 19}, { name: 'Andrew', age: 21}, { name: 'Matthew', age: 60}] // Let's say we have an array of numbers. We need to calculate the sum of its elements. const someNumbers = [10, 20, 30, 50, 100]; @@ -45,7 +45,6 @@ function imperativeStyle() { // Suppose we have an array of strings, and we would like to create an array with numbers on its basis, // each of which represents the length of a string stored in some element of the original array. - const getLength = str => str.length; // callback for our map; const someStrings = ['hi', 'yup', 'form', 'random', 'x']; // array of strings someStrings.customMap = function (callback) { @@ -58,14 +57,14 @@ function imperativeStyle() { return result; } - console.log(someStrings.customMap(getLength)); // [2, 3, 4, 6, 1] + console.log(someStrings.customMap(str => str.length)); // [2, 3, 4, 6, 1] } -imperativeStyle(); +imperativeStyleExample(); // 2. Applying higher-order functions -log('--- TASK #1 | DECLARATIVE STYLE ---'); +log('--- DECLARATIVE STYLE EXAMPLE ---'); -function declarativeStyle() { +function declarativeStyleExample() { // We have an array containing the year of birth of some people, and we need to create an array that will contain their age in 2020 const birthDates = [2001, 2000, 1992, 1969, 2010]; @@ -82,8 +81,8 @@ function declarativeStyle() { { name: 'Matthew', age: 60}, ]; - const adultGroupOfPeople = groupOfPeople.filter(person => person.age >= 18); - console.log(adultGroupOfPeople); // [{ name: 'Dmytro', age: 19}, { name: 'Andrew', age: 21}, { name: 'Matthew', age: 60}] + const adultPartOfGroup = groupOfPeople.filter(person => person.age >= 18); + console.log(adultPartOfGroup); // [{ name: 'Dmytro', age: 19}, { name: 'Andrew', age: 21}, { name: 'Matthew', age: 60}] // Let's say we have an array of numbers. We need to calculate the sum of its elements. const someNumbers = [10, 20, 30, 50, 100]; @@ -92,18 +91,17 @@ function declarativeStyle() { // Suppose we have an array of strings, and we would like to create an array with numbers on its basis, // each of which represents the length of a string stored in some element of the original array. - const someStrings = ['hi', 'yup', 'form', 'random', 'x']; const lengthsOfStrings = someStrings.map(str => str.length); console.log(lengthsOfStrings); // [2, 3, 4, 6, 1] } -declarativeStyle(); +declarativeStyleExample(); log('--- TASK #2 ---'); // The implementation and usefulness of ideas should be clearly demonstrated: Inheritance, encapsulation, polymorphism (as much as possible) // Implement in two ways. With the help of the ES6 classes and with the help of prototypes. -log('--- TASK #2 | Classes ---'); +log('--- Classes ---'); function newScopeForTask2() { // Write an abstract class class User { @@ -117,9 +115,9 @@ function newScopeForTask2() { this.nickname = nickname ?? 'Guest'; } - login = function() {}; - logout = function() {}; - writeInChat = function() {}; // Polymorphism* + login() {}; + logout() {}; + writeInChat() {}; // Polymorphism* } // Create two classes using inheritance (not abstract) @@ -143,15 +141,15 @@ function newScopeForTask2() { super(nickname); } - login = function() { + login() { this.isLogged = true; }; - logout = function() { + logout() { this.isLogged = false; }; - writeInChat = function(text) { // Polymorphism* + writeInChat(text) { // Polymorphism* console.log(text); }; } @@ -164,13 +162,37 @@ function newScopeForTask2() { super(nickname); } - writeInChat = function(text) { // Polymorphism* + writeInChat(text) { // Polymorphism* alert(`*** ADMIN ***: ${text}`); }; - deleteMessages = function(id) { + deleteMessages(id) { console.log(`Deleted message #${id}`); } + + openNewBalance() { + let balance = 0; // Encapsulation** + + function addFunds(amount) { + if (amount <= 0) return; + balance += amount; + } + + function getFunds(amount) { + if (amount <= 0) return; + balance += amount; + } + + function showBalance() { + return balance; + } + + return { + addFunds, + getFunds, + showBalance + } + } } // Create instances of these classes @@ -182,14 +204,19 @@ function newScopeForTask2() { const adminDmytro = new Administrator('Dmytro'); console.log(adminDmytro); + + let dmytroUsdWallet = adminDmytro.openNewBalance(); + dmytroUsdWallet.addFunds(5); + dmytroUsdWallet.addFunds(5); + dmytroUsdWallet.addFunds(5); + + console.log(dmytroUsdWallet.balance) // undefined + + console.log(dmytroUsdWallet.showBalance()); // 15 | Encapsulation** } newScopeForTask2(); -/* - INCAPS - get, set -*/ - -log('--- TASK #2 | Prototypes ---'); +log('--- Prototypes ---'); // Write an abstract class function User() { this.nickname = null; @@ -274,9 +301,9 @@ console.log(getFullName('Dmytro', 'Khyzhniak')); // 'Dmytro Khyzhniak' // Pure functions function strHider(str) { - return str.replace(/\w/g, '*'); + return str.replace(/\w/g, '*'); // no side-effects } -strHider('Dmytro'); +strHider('Dmytro'); // '******' // Function side effect const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; @@ -285,17 +312,15 @@ function getHalf(arr) { return arr.splice(0, arr.length / 2); } getHalf(numbers); - console.log(numbers); // [6, 7, 8, 9, 10] | Our array was changed with splice() // Unchanging state let userName = 'Dmytro'; userName[0] = 'X'; - console.log(userName); // 'Dmytro' | Immutable let newUserName = 'X' + userName.slice(1); -console.log(newUserName); // Xmytro | We can copy only +console.log(newUserName); // Xmytro | But we still can copy // Shared State let counter = 10; From f0eaec7b78b9e3be71fc6484b948aed663db79eb Mon Sep 17 00:00:00 2001 From: Dmytro Date: Sun, 14 Mar 2021 14:08:56 +0200 Subject: [PATCH 4/6] Fixed 2 of 3 issues --- HW5(OOP_vs_FP)/HW5_Khyzhniak.js | 41 +++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/HW5(OOP_vs_FP)/HW5_Khyzhniak.js b/HW5(OOP_vs_FP)/HW5_Khyzhniak.js index bc79567..d473423 100644 --- a/HW5(OOP_vs_FP)/HW5_Khyzhniak.js +++ b/HW5(OOP_vs_FP)/HW5_Khyzhniak.js @@ -24,7 +24,9 @@ function imperativeStyleExample() { const adultPartOfGroup = []; for (let i = 0; i < groupOfPeople.length; i++) { - if (groupOfPeople[i].age >= 18) adultPartOfGroup.push(groupOfPeople[i]); + if (groupOfPeople[i].age >= 18) { + adultPartOfGroup.push(groupOfPeople[i]); + } } console.log(adultPartOfGroup); // [{ name: 'Dmytro', age: 19}, { name: 'Andrew', age: 21}, { name: 'Matthew', age: 60}] @@ -334,13 +336,42 @@ func2(); console.log(counter); // 12 | Both functions are working with the same counter // Closures -function pow(base) { - return function(exp) { - return base ** exp; +function visitorsSaver() { + const arrayOfVisitors = []; // will be saved in the closure + + function addVisitors(...visitors) { + arrayOfVisitors.push(...visitors); + } + + function showVisitors() { + for (let visitor of arrayOfVisitors) { + console.log(`${visitor.name} - ${visitor.ip}`); + } + } + + return { + addVisitors, + showVisitors } } -console.log(pow(2)(2)) // 4 +const newSaver = visitorsSaver(); +newSaver.addVisitors( + {name: 'Polina', ip:'192.169.100.101'}, + {name: 'Dmytro', ip:'192.172.98.102'}, + {name: 'Sofya', ip:'193.170.120.100'}, +); +newSaver.showVisitors(); // 'Polina - 192.169.100.101', 'Dmytro - 192.172.98.102' ... + +const anotherSaver = visitorsSaver(); // Let`s make another saver +anotherSaver.addVisitors( + {name: 'not a Polina', ip:'0.0.0.1'}, + {name: 'not a Dmytro', ip:'0.0.0.2'}, + {name: 'not a Sofya', ip:'0.0.0.3'}, +); +anotherSaver.showVisitors(); // 'not a Polina - 0.0.0.1, 'not a Dmytro - 0.0.0.2' ... +// Thanks to closures we can create and save independent variables + // Recursion function getSum(num) { return num <= 0 ? num : num + getSum(num - 1); From b7274959f3d57d57f1f96594dd7f0a8428cd06ed Mon Sep 17 00:00:00 2001 From: Dmytro Date: Sun, 14 Mar 2021 20:00:58 +0200 Subject: [PATCH 5/6] Minor improvements. --- HW5(OOP_vs_FP)/HW5_Khyzhniak.js | 91 ++++++++++++++++----------------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/HW5(OOP_vs_FP)/HW5_Khyzhniak.js b/HW5(OOP_vs_FP)/HW5_Khyzhniak.js index d473423..e3cb53b 100644 --- a/HW5(OOP_vs_FP)/HW5_Khyzhniak.js +++ b/HW5(OOP_vs_FP)/HW5_Khyzhniak.js @@ -107,113 +107,112 @@ log('--- Classes ---'); function newScopeForTask2() { // Write an abstract class class User { + nickname = null; id = null; avatar = null; canWrite = null; isLogged = null; isAdmin = null; - constructor(nickname) { - this.nickname = nickname ?? 'Guest'; - } - - login() {}; - logout() {}; - writeInChat() {}; // Polymorphism* + login() {} + logout() {} + writeInChat() {} // Polymorphism* } - + // Create two classes using inheritance (not abstract) class Guest extends User { // Inheritance isLogged = false; canWrite = false; - - constructor(nickname) { - super(nickname); + + constructor() { + super(); + this.nickname = 'Guest'; } } - + class RegistredUser extends Guest { // Inheritance - id = 'some id'; - avatar = 'some avatar'; + id = "some id"; + avatar = "some avatar"; canWrite = true; isLogged = false; isAdmin = false; - + constructor(nickname) { - super(nickname); + super(); + this.nickname = nickname; } - + login() { this.isLogged = true; - }; - + } + logout() { this.isLogged = false; - }; - - writeInChat(text) { // Polymorphism* - console.log(text); - }; + } + + writeInChat(text) { + console.log(text); // Polymorphism* + } } - + class Administrator extends RegistredUser { // Inheritance canWrite = true; isAdmin = true; - + constructor(nickname) { super(nickname); } - - writeInChat(text) { // Polymorphism* - alert(`*** ADMIN ***: ${text}`); - }; - + + writeInChat(text) { + alert(`*** ADMIN ***: ${text}`); // Polymorphism* + } + deleteMessages(id) { console.log(`Deleted message #${id}`); } - + openNewBalance() { let balance = 0; // Encapsulation** - + function addFunds(amount) { if (amount <= 0) return; balance += amount; } - + function getFunds(amount) { if (amount <= 0) return; balance += amount; } - + function showBalance() { return balance; } - + return { addFunds, getFunds, showBalance - } + }; } } - + // Create instances of these classes const visitor = new Guest(); console.log(visitor); - - const user = new RegistredUser('Anthony'); + + const user = new RegistredUser("Anthony"); console.log(user); - - const adminDmytro = new Administrator('Dmytro'); + + const adminDmytro = new Administrator("Dmytro"); console.log(adminDmytro); - + let dmytroUsdWallet = adminDmytro.openNewBalance(); dmytroUsdWallet.addFunds(5); dmytroUsdWallet.addFunds(5); dmytroUsdWallet.addFunds(5); - - console.log(dmytroUsdWallet.balance) // undefined - + + console.log(dmytroUsdWallet.balance); // undefined + console.log(dmytroUsdWallet.showBalance()); // 15 | Encapsulation** } newScopeForTask2(); From 06ae2104413e603e662f480734f726d9dd03fe1b Mon Sep 17 00:00:00 2001 From: Dmytro Date: Mon, 15 Mar 2021 18:40:15 +0200 Subject: [PATCH 6/6] Improved abstract class --- HW5(OOP_vs_FP)/HW5_Khyzhniak.js | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/HW5(OOP_vs_FP)/HW5_Khyzhniak.js b/HW5(OOP_vs_FP)/HW5_Khyzhniak.js index e3cb53b..efb1a3c 100644 --- a/HW5(OOP_vs_FP)/HW5_Khyzhniak.js +++ b/HW5(OOP_vs_FP)/HW5_Khyzhniak.js @@ -107,6 +107,12 @@ log('--- Classes ---'); function newScopeForTask2() { // Write an abstract class class User { + constructor () { + if (this.constructor == User) { + throw new Error("Abstract classes can't be instantiated."); + } + } + nickname = null; id = null; avatar = null; @@ -114,9 +120,15 @@ function newScopeForTask2() { isLogged = null; isAdmin = null; - login() {} - logout() {} - writeInChat() {} // Polymorphism* + login() { + throw new Error("Method 'login()' must be implemented."); + } + logout() { + throw new Error("Method 'logout()' must be implemented."); + } + writeInChat() { // Polymorphism* + throw new Error("Method 'writeInChat()' must be implemented."); + } } // Create two classes using inheritance (not abstract) @@ -128,6 +140,10 @@ function newScopeForTask2() { super(); this.nickname = 'Guest'; } + + login() {}; + logout() {}; + writeInChat() {}; } class RegistredUser extends Guest { // Inheritance @@ -141,8 +157,8 @@ function newScopeForTask2() { super(); this.nickname = nickname; } - - login() { + + logout() { this.isLogged = true; } @@ -197,6 +213,8 @@ function newScopeForTask2() { } // Create instances of these classes + const abstractUser = new User(); // Error: Abstract class can't be instantiated. + const visitor = new Guest(); console.log(visitor);