 Welcome to this 14th part on server-side JavaScript and Node.js. This is the first out of two lectures where we go into server-side JavaScript, so lecture 17 will cover that as well, and we will do a number of things. In this first recording we will go into some advanced JavaScript concepts that so far we could live without, but it's it's important to understand them when we go into Node.js because it becomes more relevant. These things are at the same time probably the most complicated things we do in this course if you don't know JavaScript, because they are really a bit more advanced. Then in the second part, in the second recording, we will go into Node.js, so that's simply a easily speaking, it's a way to execute JavaScript outside of the browser. So, so far we have always loaded HTML in the browser, and then the HTML file has included some JavaScript, and that caused the browser to execute it. We have Node, and there are other tools for executing JavaScript without all of the HTML, all of the browser, but we'll get into that later. Now, this entire block of lectures, lecture 14-17, cover essentially server-side execution. Today we'll do the advanced JavaScript part, an introduction to Node. Then we will go into lecture 15, which is a theoretical lecture, which talks about REST, which is a style of structuring server-side programs, or generally structuring programs. There will be no coding there. Lecture 16-17 then will be very practical. So whatever we might not manage in lecture 14, we'll repeat there. There will be examples that we will build an entire API, an entire backend application. We will do some persistence using MongoDB and we'll actually deploy everything to the cloud. The learning outcomes I have here just listed for the four lecture block, because it's hard to separate them, so it's a whole bunch of things. First of all, as I've already said in the second lecture, we will go into more depth on HTTP, so hopefully after this block you will understand in much more detail what the different HTTP methods are about, what the different properties are, like EDEM potents and so on. Then we'll discuss the REST architectural style, so you should know that. Then there are a couple of practical things, like making use of a database to persist data, deploy to the cloud, and so on. Now the resources are numerous here. We have a number of references. The first three cover this first part in the recording. We will talk about immediately invoked function expressions. That's one thing. Then we have this book here. Which you might be able to access through the O'Reilly service the university has subscribed to, which it describes in more detail, for example, IFVs, but the module pattern and so on. Number three is a step-by-step introduction to the module pattern. I'll try to do that today, but if you want more reading, you can go there. Then we have Learn You Note, which is sort of an extra thing. I'll mention that later, but it's a good application to actually learn how to use Node.js, very interactive. Then we have Node.js, which is just the reference to the Node framework, the Node application. So you can go there to figure out how to install it, for example. And Express.js is a framework we will be using for server-side execution. Now, advanced JavaScript, the first thing we'll start with is this keyword. So that's a keyword that exists in most object-oriented programming languages. It's in JavaScript quite different from other programming languages. So look at this code here. We have a variable called MyVar. Then we go into a function, we say LockMyVar. There we again define a variable MyVar. Now, this is a different scope. This is the function scope. So I actually have two variables. I have one in the global scope. It's global to my JavaScript application. And I have one that is local to the function scope. It's only valid within here. And now the question is, if I do console.log this.myVar, which of the two am I actually accessing? In most programming languages, I would get B as an output. So in most programming languages, this refers to sort of the most precise, the most narrow scope. So wherever I'm right now, I'm in my function. So I'm referring to this. In JavaScript, that's not the case. So if I call my function, down here, you will actually get an A as the output. And that's something that is quite unintuitive to many people and for a good reason. We'll go into details. Now, you can also do something very different. I can, for example, say, I create a new object. So the code up here is identical to what we had before. I can say I have a new object. In this object, I define yet another variable that's called MyVar. And this time I give it C. And what I do down here now is I call my function again, log MyVar, but I call it slightly different. I call it from the context of my object. So that's something you can do in JavaScript. And suddenly you'll see that the output is C. So somehow this keyword here has changed. It's not anymore referring to this variable, but instead it's referring to this one. And a final one to maybe confuse you even more. I can have an object that contains a function. So I define my object. Again, I have a variable MyVar. And I have a variable log MyVar, which is a function that just outputs this. And then I can call it as I usually access parts of my objects. And then suddenly I get B. So now it's referring to this. So it seems like this keyword is doing a lot of strange things. And the explanation works like this. Every function, whenever you define a function, that this keyword is sort of determined depending on who owns the function or who executes it. So by default, the owner or executor of the function is where this is pointing. So for a method of an object, so if there is something in an object, then the owner of that method is the object itself. So that's the case we have here. The function log MyVar is owned by MyObject. That's why this points to MyObject. So this.MyVar is sort of the same as calling MyObject.MyVar. So that's why we get B. Now if the function is global, this refers to the global object. So that's the first case we had. Here the function is not owned. It's owned by my JavaScript file. It's in my JavaScript file. So it's owned by the global object. It's global, which means this points to the global scope, points to MyVar. That's why I'm getting A and not B. And then finally, if we have a function within a function, that's possible, then this would refer to the outer one. And then finally, if we use strict mode, I've introduced that. This is undefined by default. So you actually have to use something like down here to be very specific. This is the second case I've shown you. You can use the call function to specifically say, call lot MyVar from this thing here, from this object. And then automatically this is being pointed to whatever is in here. So that's the case I did here. I'm calling lot MyVar from the context of MyObject, which means this points to MyObject. So this.MyVar is C. This is something you need to digest a bit. Also, I don't, for example, I don't remember these things quite often. So quite often it's just that something you have to figure out when you get into a situation. Of course, if you use JavaScript every day, you will at some point internalize this. You understand it very well. But if you just do it sporadically, then every time you'll maybe have to look up again how this works. But it's quite common to get these things wrong because quite some people are used to just using this in the way it works in other programming languages. Now, there are some issues with this that are easily missed, I would say. This is exactly what I had, what my third case was. I have a variable here. I have an object. The object contains MyVar and it contains the function. What I've done now, I've done it slightly different. Instead of just logging, I've put the log into a timeout. And I don't care whether this takes a second or zero milliseconds or whatever. But the point is the console log is within a timeout function. And now it's getting tricky because setTimeout, you remember this is handled by the browser API. So it goes somewhere else. And then we have an anonymous function in here. It doesn't have a name. And this means in JavaScript that this function is executed globally. So suddenly, since this is executed globally, the owner of the function is the global object. So this points here. It points to MyVar. So suddenly, the output here is again A. Because we're pointing here. And that's something that's quite often unexpected. That's quite often something that might confuse you when you do callback functions, for example. So these kind of things you might run into. Now, the reason, well, it's not the only reason, but the reason why we have this behaving so strangely is maybe one of the causes for having arrow functions, which were introduced in JavaScript version ES6. And arrow functions, I wouldn't introduce per se, but they're very common in many libraries, in many code examples. So you probably already have seen them. That's why I want to show you to them as well. So an arrow function is just a short version of a function definition. If you look at this, that's what you know. It's a regular function. I have two parameters. I have my curly brackets and I'll return something. The same as an arrow function looks just like that. So I just skip the function keyword. I just have my parameters. Instead of the curly braces, I just have this arrow equals greater than, and then this is what I return. So that's exactly the same function, more or less. And of course, you can do things different. So for example, if you have no parameters, well, it's just an empty, empty bracket, return 42. And you can assign that to something if you want. But now this looks pretty strange. But it's exactly the same again as writing equals function return 42. So it's just a short version. And then sometimes you have more than one statement. So here, what we did here is always, I returned exactly one thing. So I don't need curly braces. But if you have more than one line, for example, first, I want to log something, then I want to return something, then you also need the curly brackets in an arrow function. So you cannot leave them out. If I would leave them out, then only the first statement would be would be interpreted as part of the function. And the rest would sort of be treated as the next statement. It's not within the function anymore. That's the same in many programming languages. For example, if you have an if, if you have an else, whatever is in that if or else, if it's just one line, you can leave away the curly braces. That's quite common. But as soon as you have more than one line, you need them. Now arrow functions have one specialty. And that's related to this, which we just discussed. Arrow functions don't have this. So they're always inherited from the parent. So we said earlier, in a function, a function always defines its own this keyword. And then this depends on who owns the function or how we call it. Arrow functions do that slightly different. So in an arrow function, what we do instead is inheriting from the parent. This one here, that's exactly the same case as before I had my time out. The difference is what I changed now is instead of writing function, I'm using the arrow function expression. And now suddenly we have a different case. We don't define a new this keyword within the function. Instead, we inherit it. And the inheritance causes us to inherit this from up here. And this keyword in the context of this function is my object. My object owns this function. So this within here points to my object. The arrow function doesn't define a new one, which means this points exactly to the same thing as that this keyword in function, it points to my object. So this refers to our object in the end, which means the output of that statement will not anymore be a, but it will point to my object. So it will be my object dot my war. The output will be B in this case. And again, this is something that is quite confusing. And I would recommend you, I upload all the code I have here as JavaScript files, I would recommend you to go through that and to try to understand what's happening in the different contexts. This is quit the way I'm going through it right now. But that's an important thing to understand. And that's also why quite often you see this arrow expression. So in this case, we're not saving a lot of space by using this notation. But it's much easier to access the variable we might want to access compared to the case when we wrote function because then we were suddenly up here. So that's why it's used in many cases. Okay, so that so much for this keyword and for arrow functions, what we'll do now is we go into two more concepts. And for the first one, I have to first take a step back and then discuss some terminology. Because we often talk about these things, but they might not be clear. We have assignments in programming languages, we have declarations, and we have expressions. And they're quite different. So an expression is something that returns a certain value that can be evaluated. So for example, you all know the equals notation x equals five, this one returns either false or true depending on what x is. So if x is five, then this will turn true. Otherwise, it will return false. So JavaScript looks at that sort of calculates the result and returns it. Now, this is very different, of course, to an assignment. If we say x equals five, then we assign the value five to x. So we are changing the values up here, we're not changing x anyhow, we're just evaluating something. Now, in depending on the programming languages, assignments can actually also return values. So that differs a lot in some programming languages, there is no return value. An assignment just doesn't return anything. In other programming languages, an assignment returns, for example, the assigned value. So this depends a lot. And it's not that important here. So we have those two things. And then finally, we have a declaration where we declared that the variable exists. So here we tell JavaScript, there is a variable x, please keep track of it. And from then on, JavaScript knows what x is. To maybe confuse that, we quite often see something like this, var x equals five. That's both. So it's both a declaration and an assignment, var x declares the variable and x equals five assigns a value. We could make this worse, we could put all three in there. If we, for example, say var x equals x double equals five, then we would first have a declaration, then we would assign a value. And the assigned value is the result of an expression. So we could put all three things together. But it's important for you to know that these things exist and know the difference. Because now the next step, we do something that requires you to understand the difference between expressions and a declaration. And those are so-called immediately invoked function expressions or IIFEs. What they are basically, well, they are a function and they are an expression somehow. If we take one definition that an IIFE is a JavaScript function that runs as soon as it is defined. So usually, as we have done before, let's see an example. Here we have a function. We define this function, but it's not being executed. It's only executed when we actually call it from the code. Now, in an IIFE, what we do is we write our function. Here it is. But then we add some things. And those are the things that I've put bold and underlined here. So we put the function into regular brackets. Then we put the double bracket afterwards. And that's like executing it. Please run this function. And then we have the semicolon. And what happens now is, as soon as this code is read, as soon as this code is parsed, this function is executed. So in this case, it says x equals 2 and then it does 2 square. That's 4. So this just returns 4. And the result is that we define a variable result and we assign the return value of this expression, which is 4. So the result is that result equals 4. The interesting thing now is this function can never be called again. It's an anonymous function and we put it into this expression. All we do is we say, as soon as you get here, call this function and assign the return value to result. And then we're done. We cannot call this again. So that kind of explains to you what this name means. We have a function that is invoked as soon as it's read. It's like immediately invoked. And this is kind of, it's an expression because it returns something. We evaluate what's going on here. We check what's the return value and we return that value. So it's quite similar to something like x equals 5. W equals 5. We're kind of evaluating what is the result of this and we assign it to result. So that's what it is. It's an immediately invoked function expression. Now there are some interesting things with this. And the first one is we declare a value here. We declare x and we assign 2. And because this x is within the function, it cannot be accessed from outside. So as soon as the function is called our x is gone and we can never access it again. So IIFE's what they actually can do is they create some sort of privacy. So here we only return square of x. We return 4. There is no way to access the variable itself. It's sort of private. And that's a very interesting thing because otherwise we don't have that in JavaScript. We don't have this privacy that you can make things private and it cannot be accessed properly. So that's what we can do with IIFE's. And that's exactly why I'm actually introducing them because you can use IIFE's to create modules, to create reusable parts in JavaScript where some things you want to expose, some things should be accessible, other things you want to have private. And that's a very common thing in programming. We want to have encapsulation. So that's what we'll use it for. And I'll introduce that now step by step. And that's then the last advanced concept that we do. So in the first step we could, if we have data and functions that we want to have that are kind of coupled that are together, we typically create an object. For example, here we have var my person. It's an object. And it has an SSID. It has some kind of social security number. And we have functions that we can use to access it. We can get the SSID. It just returns it. And this get function is also calling a log function. And the log function just prints something. So this is just, for example, we could use this to say, well, this is sensitive data. Whenever someone is actually requesting it, we put somewhere into our logs we put that it has been accessed. This function is not very useful here, but we could use this. For example, if we would add more details, we could say who is the person that has requested the social security number and save it in our database, for example. But the important point is, what we would like to do is to say, if someone directly tries to access the attribute, this should be undefined. This should not be possible. Because the ID itself should be private. You have to use the functions. If you can access it directly, then for example, we're not logging anything and that's not good. The other thing, the logging function itself should be private. No one should just say, please log. This should only happen internally. Whenever we call it get log should be called. But no one should be able to call it directly, because it doesn't make sense. In this case, for example, I'm not really accessing the SSID, I'm just logging something. The only thing I want to be able to do is to use the get SSID function. Ideally, I would like to have an object or any kind of module, any kind of thing that exposes this function here and keeps the other two private, keeps the other two protected from the outside. That's exactly what I would like to do. Now, the problem is in an object, in this case here, everything can be accessed. So I said here, this should log undefined, but it actually doesn't do it. It works without problems. The logging works without problems. The get SSID works without problems. So nothing here causes any issues. And that's not what I want. So the first step I could do is to use an IIFE, what we have just learned. So I change my object to start with. It's not an object anymore, but instead I define a function where I define all my three things. I define my attribute and my two functions. And I wrap the entire function definition in an IIFE. What happens now is as soon as this code gets parsed, this function gets executed. And whatever is returned is assigned to my person. That's our first step. The problem is nothing can be accessed because our function does not return anything, which means it returns undefined. So my person will actually here be undefined. So now I've sort of gone too far in the previous case. I could access everything. Now I can access nothing. I just get undefined. That's also not very useful. So now we get to the last and interesting step. We have successfully hidden everything in here. Now we just have to actually expose whatever we want to access. And we just do that by returning whatever we want to access. So in our case, we just return a new object and all it contains is our function here. So we just say, please return an object that contains the attribute get SSID, which happens to be this function. And now I have the access exactly as I wanted. If I do my person, here we have my person, my person dot SSID, it won't be defined because it's not returned. It doesn't know what this is. If I do log SSID rack, it's exactly the same. I haven't returned this function. So it's not accessible here. If I do get SSID, it actually will work. It will call this function. And maybe the most interesting part to us, this function actually knows all the internal things. So it's not like these, this variable and this variable just disappear. They can still be accessed within the IFE. So this is now sort of the full circle. I managed to create a data structure that has private parts that I don't want to expose. And it has public things that you can call. And I can define exactly how I want that to be. So that's an important thing for structuring larger programs. Because of course, here we talk about privacy, no one should be able to access the ID directly. But this is of course, also a quality issue, because if I can directly access a variable, I might cause bugs in the program. If that is not expected, for example. So this is a very typical thing you want to have in programming encapsulation. And we managed to do that now by using these IFEs. Okay, to summarize this part, we essentially did three things. We covered this keyword, which is quite different from other programming languages. And you need to have some time to understand this. So please look at the code examples. We then went into the arrow functions, which are just a short version of regular function definitions. But they actually don't have their own this keyword. So they, well, I'm not sure they really help us avoiding problems, but they give us other opportunities. And sometimes no one cares about this. Sometimes they just use to write less code. Then the third part, we went into what IFEs are. So immediately invoked function expressions. And we use them to build modules. So parts where we can hide certain things and expose the things we want to. And essentially, those things now are reusable entities, modules that I can include in my code somewhere else. This is highly important because most JavaScript libraries use modules. They have internal parts which you should not be able to touch. And they have things that you can call directly. Once we get to Node.js, there is an easier way of doing this. We don't always have to define our IFEs, but it's important to know how you would do this by hand if you actually write plain JavaScript code. JavaScript libraries, JavaScript frameworks, a lot of them make heavy use of arrow functions of this. That's why you need to know them. And of course, modules are extremely common as well. That's why I taught you that part as well. But now in the next part of this recording, we'll finally go into Node.js and actually execute JavaScript code outside of the browser.