- ECMAScript6 came out in 2015
and it completely revolutionized the JavaScript language.
For example, it introduced full support
for object-oriented programming.
At last, we had a proper way to define classes
and to create objects and to use inheritance.
So I'm not gonna go into the theory of OO programming here.
I'm sure that you are familiar enough with it.
So what we'll do instead is we'll just review the syntax.
In this section, I'm going to review the syntax
for defining classes and using objects in ECMAScript 6.
And then in the next section,
we'll see how to test classes using Jest.
So first of all, how do you define a class in JavaScript?
It looks like this. Class is a keyword
and class names usually have a capital letter
like Account, bank account.
Constructor is a keyword
and it's the initialization function.
When you create the new account object,
it'll call the constructor, and you pass
in parameters to initialize the object
with whatever fields you're interested in.
So I pass in my name, Andy,
maybe in the balance a million,
and it stores the name in this object.
This is a keyword.
It identifies the current object that we are constructing.
And whenever you're accessing members in a, in a class,
you have to say this, inside this object,
it now has a properly good name,
which receives the incoming parameter.
And this, this object
this bank account object, also has a balance,
which receives the incoming balance parameter like so.
I can deposit money into this balance for the object.
I can withdraw money from this balance in the object.
So that's a very simple class definition.
Once you've defined a class, you can then create an object.
An object is an instance of a class.
You say new, and then you give it the name of the class,
and this will create the new object
and it'll call the constructor.
And the constructor will add a name property,
set it at Peter,
and add a balanced property, set a set of 5,000,
and you get back a pointer. Acc1 is appointed
to the object that you've just created.
And upon that object, you can invoke methods.
On this object, invoke the deposit method.
Peter now has a balance of 5,200 pounds,
and you can withdraw money as well.
Notice you can also access data.
That's interesting. If you've done C sharp
or Java or C++, you'd be surprised
by that because in other, in those languages,
data is private, but in JavaScript, it has a simpler model.
Basically everything in a class is public,
even the data, which might go
against the grain as an OO programmer.
But you know, that's how it is in JavaScript.
It's a simplified syntax.
Okay. So just to kind of summarize classes in ECMAScript 6,
modern JavaScript, compared to other languages,
there are some differences.
You don't define members
at the top of the class in ECMAScript.
Instead you add properties within the constructor.
When the object is created, it has no properties initially.
When the constructor is invoked,
the constructor dynamically adds properties to the object.
As the object is being constructed,
properties get added to it dynamically.
In fact, you can add properties to an object
even afterwards. An object, essentially, in JavaScript,
is more like a map with properties
that you can add and remove dynamically
because JavaScript is a dynamic language, which is
has its plus points and its negative points as well.
You don't define anything as public or private.
JavaScript doesn't have public and private.
Basically everything in a class is public.
And that does take a little getting used to
if you're coming from a stronger OO language,
like almost any other language you can think of, actually.
So if you're familiar with classes or how to
emulate classes before ECMAScript 6, in ECMAScript 5,
you would define a constructor function.
And the constructor function would behave like a class
and it would have prototype objects to define methods.
So if you're familiar with how ECMAScript 5
used to emulate object orientation, underneath the covers,
ECMAScript 6 gets converted into that syntax.
So when you define a class in ECMAScript 6,
it actually gets converted into an ECMA Script 5
constructor function and with a prototype object
that houses the methods.
If you've never seen this before,
then you can ignore what I've just said
for the last 30 seconds.
You don't need to know how it works.
You can just use the syntax.
So what we're gonna do now is we're gonna have a look
at a more realistic example of classes that
actually do something useful.
Have a look in this folder, Mocking Classes,
IntroES6Classes, have a look in there. Okay?
So that's the folder, Mocking Classes, IntroES6Classes.
Later on, in later sections,
we're gonna see how to mock and test those classes,
but let's just look at the basic syntax for now.
If you open that folder in a code editor,
it looks like this.
And what you'll find is I've defined two classes.
I define a class rest Client and product Manager.
So there we go.
We have a rest Client class, which calls a rest service,
and a product Manager class, which collect
contains a collection of products.
It allows me to add products and remove products
and calculate the average cost of products
and that kind of thing.
So let's take a look at these classes now
and get a feel for the syntax.
We'll have a look at the rest Client class first.
So rest Client is in here, and what can I say?
Well, first of all, it is going to be,
this is gonna be in JavaScript.
And the idea is that this class is going to
encapsulate calls to a remote rest service.
So I'm gonna use Axis.
Axis is quite a popular library for call-in rest services.
So, and it's a standard library as well.
In my package.json, I include the dependency for Axis,
so I can actually make Axis calls in my code.
Okay, well that's the technical detail.
In my rest Client, it's going to encapsulate calls
to a rest service.
So the constructor, when you create one of these objects,
you have to pass in a base URL.
What is the URL of the rest service that you're gonna call?
What's the base URL?
And then I've got, I've got a crowd interface.
Basically this method, get All, using Axis under the covers,
It sends in a get request to the remote URL.
That's the URL that we specified there on the server.
That returns a promise object.
Then the result comes back.
When the result comes back,
we take the http response,
which is the entire http response body from the server,
and from there, we extract the data in the http body
as probably json, and that will extract
the data and return it back.
What this function actually returns is a promise,
a promise that this data will be available when
the rest service is complete.
The rest service might take a second,
or two seconds, or three seconds.
The promise object will eventually be resolved
with the data back from the server.
That's to get all products.
You can get one product with an ID parameter.
So what it does, it uses, this is
an ECMAScript interpolated string.
It embeds the URL and it follows it by the ID.
So it'd be something like
example.com/products/1234, the ID.
And presumably that would return back one product
as a promise. When that promise has been resolved,
take the http response, the whole body,
and extract the payload, the http,
the data from the http response.
And this promise gets returned back to,
to my user interface.
So typically you would call, this low level class,
you would call it from the user interface layer,
maybe, in your code.
It has an update method, and the update method is
takes an ID representing an existing product.
And, and basically the new data for the product.
It's like a replacement.
It's like when you have, if you have,
imagine you have a row in the database,
it would completely change that row
with a new set of data for an existing row.
So you give it the ID for the products in the database,
maybe the existing product,
here's the new data for that product.
So we call Axis as a put function, which is an update,
or rather, it's like a whole object replacement.
That's what it does.
It sends in a put request to the URL
like example.com/id 1, 2, 3, 4, whatever the ID is.
And plus, in the body, it sends in the new data.
When you send, when you have a put request,
the URL specifies the ID of the item to change, and the body
of the http message is the new data that you're gonna send
to the server in the http respo- request body.
And then finally, delete, you just need the ID,
and you send in a delete request.
Okay? And presumably at the server,
that'll delete the item from, from a database, maybe.
But in terms of JavaScript class index,
it is quite a realistic example.
It's a class, it has a constructor to remember the URL,
and it uses the URL in various different places here.
And then it has various methods to provide a CRUD,
to create, read, update, delete, API.
That's one class.
And then I've got another class here, product Manager,
which is a more kind of semantic class.
This class here is quite low level,
but the product Manager class is more
at a higher level of being.
So it also has a constructor,
and it creates one of those objects,
the object I've just shown you, it creates one of those.
It creates a rest Client object.
It creates one of those.
And it passes in a constructor parameter.
This is the base URL that the rest Client object ...
Oh, by the way, RC is the, is the rest Client module.
Okay? So whenever, when you, when you import a model,
RC is like a prefix for anything defined in there.
So rc.restClient, it says go to the RC module,
which is this one.
And in that module, you'll find a class called rest Client.
There we go. Okay.
So the, basically the module alias, and then the class
inside that module, it has a constructor, and we
pass that parameter into the constructor.
Obviously this is an artificial example.
Oh, and then I've got a business method
to get the stock account.
So I take my rest Client and I get All products.
So presumably, in a real application,
that would've gone back to the server,
and that returns back a promise, a promise
that will eventually be resolved with all the products.
So I say, well, when that product has been resolved,
when the rest service has finally come back,
I will have here an array of products.
So what I do is I take the products and I take
That's a lasting array of products, presumably.
For each product, I call the map function.
The array class in JavaScript has a map method,
and it'll basically transform each product into
just the stock level.
Imagine the product class had a stock property.
How many items in stock for that particular product?
So I've taken my collection of products, and I've
converted it effectively into collect, a collection
of stock numbers.
What I then do is I call the reduce function.
We've seen this before, and the reduce function
is quite clever.
It basically rolls two parameters into one.
It takes the cumulative total,
and then the next value from this collection.
Okay. So this basically is a collection of stock levels.
It'll pass the first stock level into there.
And the, the initial value for the total is zero.
When you call the reduced function,
you pass in two parameters,
a lambda that says how to reduce two values into one.
And the second parameter is the, if you like, the,
the initial value for your accumulator.
So zero will be the initial value for the total,
for the first time of call.
It'll then pass the first product's stock into here.
And it'll add the current total,
which is zero, to the stock level for the next product.
And that value then gets passed in to the next incarnation.
It calls the function again with the current total
and the next product
and it adds the next product to the total.
And that running total then gets passed in again
into here, followed by the next product.
So it kind of marches from left to right, starting at zero.
It'll accumulate the total stock.
That basically gives me the total stock level
of products in my catalog.
That's assuming that when I called the rest service
it resolved successfully.
It could have failed. When you call a rest service,
it can fail for a number of reasons.
So you, you should also handle the catch possibility.
In the catch possibility, we say, like,
I've got some kind of error message.
I don't really care about the error message.
All I'm going to do is return the value zero.
So this function will either return the result of this,
you know, accumulation of stock levels,
or it'll return zero in the case of an error.
The second function is quite similar.
Instead of getting the, no, the cumulative total
of how many items do I have in stock,
it tells me the overall value of all my items,
by multiplying the stock level for product by its price,
and then adding those numbers together.
So the same idea, get all the products from the rest Client.
When that data's back, get all the products from the,
from the promise. For each product,
tell me it's, kind of, line value.
What's the price of one product multiplied
by the stock level, and then add those numbers together
in the same ways we did just now.
And that will tell me, that will return back
the total value of my catalog, how many products
and how much do they cost? Add those numbers together.
That's the, the total stock level for your,
for your catalog.
Or zero, of course, if anything goes wrong.
Oh, and then I can remove products.
Now this one here, this syntax,
have you seen this syntax before in JavaScript?
It's a variadic, it's called a rest parameter,
nothing to do with rest services.
It means you can pass into this any number of IDs,
like 1, 7, 3, 6, a comma-separated ... like an array almost,
and what it does, it'll take all of those IDs,
and for each ID, it'll basically invoke the rest Client
to delete the product with that ID.
So I passed in here, 1, 2, 3 ... whoopsie Daisy!
If I passed in here, 1, 2, 3, 4,
it would iterate through that collection, 1, 2, 3, 4,
and it would delete product one.
And then it would delete product two,
and then it would delete product three,
and then it would delete product four.
So for this comma-separated sequence,
it'll call the delete for each ID.
So that's quite smart,
additional bonus feature in this example.
So what we've seen here is how to define classes,
quite realistic, actually,
you know, these are the kind of classes
you would write in a, in a JavaScript application.
What we're gonna see in the next section
is how to test these classes.