Lesson 1 - Introduction To Object-Oriented Programming In JavaScript
Welcome t
o the first lesson of the object-oriented JavaScript programming course. We've already finished the JavaScript basic constructs course. In this course, you'll learn to program in an object-oriented way and will also develop an object-oriented way of thinking. It's a bit different than anything we've done until now. For starters, we'll no longer treat programs like several lines of code that the interpreter executes one by one.
Why To Program In the Object-Oriented Way
Knowledge of object-oriented programming in JavaScript is absolutely crucial just because everything is an object in this language. Although we can use objects without fully understanding them up to some point, third party frameworks like Angular or React will require us to have a deeper understanding of this issue. And your employer will require you to know these frameworks or you're going to need them because of the complexity of your own projects Developing a serious project without objects is more laborious, more demanding, and the results will always be poor.
Object-oriented programming (hereinafter referred to as PLO) was not created by chance, but is a consequence of the development that was directed towards it. It is a modern software development methodology supported by most programming languages. A common mistake is that people believe that PPE is only used when writing a particular type of program and is otherwise harmful. The opposite is true - OOP is a philosophy, it is a new perspective on the function of the program and communication between its parts. It should always be used, whether we are doing a small utility or a complex database system. OOP is not just a technique or some recommended structure of the program, it is a new way of thinking, a new perspective on problems and a new era in software development.
The invention of object-oriented programming, OOP hereinafter, was no coincidence, but the result of a development which led to its creation. It's a modern software development methodology supported by most programming languages. A common mistake is that people think that OOP should only be used for certain kinds of programs and that for other cases it would be needlessly complicated; however, the opposite has proven to be true. OOP is a philosophy. It's a new way of looking at a program and the communication between its parts. We should always use it whenever we create a simple utility or a complex database system. The OOP is not just a technology or a recommended program structure, it's mainly a new way of thinking. A new perspective from which we could analyze problems and a new era in software development.
As first, we'll look quickly into the history of how people programmed before OOP and what specific problems OOP resolves.
The Evolution of Methodologies
There's a big difference between programming nowadays and programming 40 years ago. The first computers didn't have great performance and their software was quite simple. The evolution of hardware is so fast that the number of transistors in microprocessors doubles every year (Moore's Law). Unfortunately, people aren't able to evolve as quickly as hardware does. Faster computers require more and more sophisticated and complex software (people want more and more from their computers). So much that at one point, it was found out that about 90% of all software doesn't meet deadlines, requires additional costs or isn't finished at all. Developers started looking for new ways to write programs. Several new approaches took turns. More precisely, paradigms (ways of thinking). Listed as follows:
1 - Machine code
The program was just a set of instructions where we weren't able to name variables or enter mathematical expressions. The source code was obviously specific for the then current hardware (processor). This paradigm was replaced soon after it was established.
A program adding two numbers (83 and -2) would look like this:
2104 1105 3106 7001 0053 FFFE 0000
As you can see, programming in machine code isn't a good idea. Even basic tasks required several lines!
2 - Unstructured paradigm
The unstructured approach is similar to the assembly languages, it's a set of
instructions which are executed line by line. The source code wasn't dependent
on the hardware and was human readable. This approach enabled the creation of
more complex programs for a while. There were still many pitfalls: the only way
to repeat something or to branch off a code was the GOTO
statement.
GOTO
allowed to "jump" to different locations within the program.
Locations were previously specified by a line number in the source code, which
is obviously impractical. When we insert a new line of code somewhere, the
numbers no longer match and the code is broken. Later, it was made possible to
define what they then called "labels". This approach served as a way of
simulating loops. This method of writing programs is of course very confusing
and soon failed to be sufficient for developing complex programs.
Our example would look like this in ASM:
ORG 100 LDA A ADD B STA C HLT DEC 83 DEC –2 DEC 0 END
Remember that the enormous improvement and expansion of computers over the past few decades has been the cause of the growth of software demand and the growth of programmer demand as well. Certainly, there are people who can write bulletproof programs in ASM or other low languages, but how many are there? How much would cost to hire this superhuman? It is necessary to have a way that even less experienced programmers could use to write high-quality programs and not have to go through 5 years of trial and error to do so.
3. Structured Programming
Structured programming is the first paradigm that lasted for a longer time and was quite sufficient for the development of new programs. They would mostly program using loops and branching. Conceptually, we are in the structured programming era based on what we have learned from the first course.
The script would be decomposed into functions, we've already practiced that on many examples. In structured programming, we meet a functional decomposition principle. A problem is decomposed into several subproblems and each subproblem is then solved with some parametrized function.
The disadvantage to it is that a function can only do one thing and when we want a different behavior, we have to write a new one. There is no way to reuse old code and modify it. We need to write it again and again - this creates unnecessary, potentially costly, errors. This disadvantage can be partially worked around by using parametrized functions or using global variables. However, such universal functions usually require a lot of parameters to pass and are hard to use and maintain.
With global data, there's another pitfall. Functions can access the data of other functions. This is the beginning of the end, we can't guarantee that global data isn't being overwritten somewhere between functions. It leads to uncontrollable problems. The entire program will consist of unencapsulated code blocks and can hardly be maintained. Any modification increases the complexity of the program, and then the program will necessarily come to a situation where the cost of adding new features will overbalance the value added by these features. Languages using this approach are, for example, the C language and Pascal.
Our example would look like this:
function add(a, b) { return a + b; } let c = add(83, -2); document.write(c);
In JavaScript, it's sometimes ok to write a short script without using object-oriented programming. However, if it starts to grow or we even plan to create something larger, without objects we'd necessarily come to a point where it wouldn't be possible to expand the program anymore and we'd either have to discard it or rewrite it using OOP.
The non-object-oriented methods of writing code are called "spaghetti code" because of their lack of clarity (everything is tangled together like spaghetti).
The Object-Oriented Approach
OOP is a philosophy and a way of thinking, designing and implementing solutions that focuses on reusability. This approach is inspired by the industrial revolution - the invention of basic components. For example, when we build our house, we don't burn our own bricks and forge nails, we order them.
Making a "component program" is smarter and cheaper. Components don't fail, they're tested and maintained. If there's a problem, it is most likely in the code you have written in one specific location. We're motivated to write clear code since it can be used by others or by ourselves in other projects. Let's face it, humans are lazy by nature and if we thought that our code wouldn't ever be reused, we simply wouldn't write it good enough ).
Of course, we'll use the knowledge we have gained until now. The main difference is that now, our code will be structured differently into multiple communicating objects.
Let's show our example once again, this time using objects. The
add()
function will be no longer global, but it'll belong to the
Calculator
object, which is one of our application components.
'use strict'; class Calculator { add(a, b) { return a + b; } } const calculator = new Calculator(); let c = calculator.add(83, -2); document.write(c);
The code doesn't tell you much yet. We'll fix this in the next lesson, The First Object-Oriented Application in JavaScript, explaining everything in detail and creating your first object-oriented app