JavaScript supports object-oriented programming, but unlike most of the other mainstream languages, it offers prototypal inheritance instead of class-based inheritance. The updated syntax for inheritance is similar to the one in Java, but the semantics remain true to the roots of JavaScript. It is much easier now to use inheritance and to override methods. The code is easier to understand and to maintain, and it is not prone to errors as it was in the past. Furthermore, you can directly and comfortably use inheritance instead of relying on libraries to do it for you. In addition to supporting inheritance, JavaScript provides a special symbol, species, that can be used to control the type of instance that’s created when working with inheritance.
In the next chapter we will explore the new modules capability in JavaScript that helps to split up large projects into cohesive multiple files.
These exercises will help you practice inheriting from built-in classes and to extend their capabilities. You can find answers to these exerciseshere.
The Set class provided in JavaScript can use some extensions. Let’s create FunctionalSet to provide filter(), map(), and reduce().
| 'use strict'; |
| |
| //Your code goes here |
| |
| const set = new FunctionalSet(['Jack', 'Jill', 'Tom', 'Jerry']); |
| |
| const jSet = set.filter(name => name.startsWith('J')); |
| const allCaps = set.map(name => name.toUpperCase()); |
| |
| const totalLengthOfJWords = |
| set.filter(name => name.startsWith('J')) |
| .reduce((total, word) => total + word.length, 0); |
| console.log(jSet); //FunctionalSet { 'Jack', 'Jill', 'Jerry' } |
| console.log(allCaps); //FunctionalSet { 'JACK', 'JILL', 'TOM', 'JERRY' } |
| console.log(totalLengthOfJWords); //13 |
The add() method of Set returns the instance of Set with the added element. In the previous exercise we inherited from Set and our FunctionalSet provided three extra functions. However, we never called add(). Let’s change
| const set = new FunctionalSet(['Jack', 'Jill', 'Tom', 'Jerry']); |
to
| const set = new FunctionalSet(['Jack', 'Jill', 'Tom', 'Jerry']) |
| .add('Bill'); |
What change do you have to make for your solution in Exercise 1 to work for this modified code?
Implement a BoundedSet that inherits from Set to provide the desired behavior shown in the code:
| 'use strict'; |
| |
| //Your code goes here |
| |
| const set = new BoundedSet(5, ['Apple', 'Banana', 'Grape', 'Mangoe']); |
| |
| set.add('Orange'); |
| set.add('Apple'); |
| |
| try { |
| set.add('Tangerine'); |
| } catch(ex) { |
| console.log(ex.message); //exceeded capacity of 5 elements |
| } |
| |
| set.delete('Grape'); |
| set.add('Peach'); |
| console.log(set.size); //5 |
| |
| const set2 = new BoundedSet(2, ['Apple', 'Banana', 'Grape']); |
| console.log(set2.size); //0 |
| console.log(set2); //BoundedSet { capacity: 2 } |
Complete the code so it produces the desired result, using the modern JavaScript conventions:
| 'use strict'; |
| |
| class Base { |
| copy() { |
| //Your code goes here |
| } |
| } |
| |
| class Derived1 extends Base { |
| //Your code goes here |
| } |
| |
| class Derived2 extends Base { |
| //Your code goes here |
| } |
| |
| const derived1 = new Derived1(); |
| const derived2 = new Derived2(); |
| |
| console.log(derived1.copy()); //Base {} |
| console.log(derived2.copy()); //Derived2 {} |
We will combine two classes that inherit from a class in this exercise to produce the desired result:
| 'use strict'; |
| |
| class SpecialWordChecker { |
| isSpecial(word) { return word !== word; } |
| } |
| |
| class PalindromeChecker extends SpecialWordChecker { |
| //Your code goes here |
| } |
| |
| class AlphabeticalChecker extends SpecialWordChecker { |
| //Your code goes here |
| } |
| |
| const checkIfSpecial = function(specialWordChecker, word) { |
| const result = specialWordChecker.isSpecial(word) ? 'is' : 'is not'; |
| console.log(`${word} ${result} special`); |
| }; |
| |
| const palindromeChecker = new PalindromeChecker(); |
| checkIfSpecial(palindromeChecker, 'mom'); //mom is special |
| checkIfSpecial(palindromeChecker, 'abe'); //abe is not special |
| |
| const alphabeticalChecker = new AlphabeticalChecker(); |
| checkIfSpecial(alphabeticalChecker, 'mom'); //mom is not special |
| checkIfSpecial(alphabeticalChecker, 'abe'); //abe is special |
| |
| //Combine PalindromeChecker and AlphabeticalChecker here |
| const alphabeticalAndPalindromeChecker = //Your code goes here |
| |
| checkIfSpecial(alphabeticalAndPalindromeChecker, 'mom'); //mom is special |
| checkIfSpecial(alphabeticalAndPalindromeChecker, 'abe'); //abe is special |