[ Silence ] Welcome to Section 4 S-75. This is July 18th, Wednesday evening. We're going to be talking about JavaScript this evening and about JQuery and about the document object model. So, as always with my sections, my name is Myer [assumed spelling] and I'm one of the TFs for S-75. You can find the code that I talk through tonight at github.com/codekiln/S75-Sections and if you just go to that URL and then scroll down their instructions on how to view the code in the CS50 Appliance so that it appears for you like it does for me right here. This is the CS50 Appliance over to the right. So first since we're at this page, I'd like to point out a few new links for this week. I've put in some links to some JavaScript videos by Douglas Crockford. Each one of this is about an hour long, so you probably don't have enough time to watch it before next week but all of these are great. I have a bit here about JSLint specifically about how to install it. David talked about that at the end of class and we're going to go through a little bit of that this evening as well. Finally, there are some links to JavaScript documentation generation in the spirit of JavaDoc or like PHPs documentation generation capabilities. And finally, there's a link to JSFiddle which a great place to test JavaScript online. Up in the left hand quadrant here you see the HTML that the JavaScript operates on and here in the lower left quadrant you see the JavaScript that you are able to do. In the upper right quadrant you are able to enter in CSS and then the result appears in the lower right hand window. And you can even link to your specific example with JSFiddle. So, I highly encourage you to mess around with JSFiddle when you're thinking about a user interface prototype for one of your assignments. Maybe you can mock it up here and then once the interface details are kind of flashed out, you can move it into production mode. So this evening we'll be working through the July 18th code, which is right here. So I'm going to change directories into July 18th and let me just get it up here. So tonight, the first example I wanted to run through is a quick example of how to make PHP recourse through the directory tree beneath the directory that the file that houses a certain PHP code is and print out the results of the directory tree. In a sense, that's what Apache does for us right here except they don't expand the sub nodes automatically. You actually have to go to another page in order to get the listings of the subdirectory. So here's our first example, you'll see I've structured the folders a little bit differently because in our assignments we're now putting the index.php, that is the point of entry into the application, in the HTML directory and so we have to step into the HTML directory in order to see the result. So when we step in, you can see that these are all the files that are inside of the folders, private PHP and HTML. If I go back and go into private underscore PHP you'll see those files available. So, I did this structure in order to give a simple example of what David was talking about. David mentioned that we want one directory that houses all of the public facing files. All of the files that are chmoded 644 world readable and then the single index.php that's the entry point into your application and then from there including all of the other business logic that is stored in a separate folder that-- maintaining that separation makes it easier to make sure that your business logic, which is private to you and private to the business you're representing if you happen to be working for a client, making sure that that business information is actually kept private in case you flip one line of code in httpd.com or php.ini that actually spits out all the PHP to the screen as text rather than processing it. So, if I use the tree command, I'm not sure-- yeah, it's installed here. You can see the directory structure mimicked like how it is here. This tree command is kind of the inspiration for this little application. If I step inside html/index.php you'll see that I basically set some constants and then include the controller. [ Typing ] And the controller calls the model, sets a few configuration variables and then calls the view. So let's just take a look at the view or actually let's take a look at the model. Inside model.php is two functions, php file tree and php file tree dir. And both of these functions are the functions that recourse through the subdirectories and generate the HTML that is seen here if I do view page sort or a view page source. The way that it generates an unordered list with a list item and then a link and then it closes the unordered list for HTML. All of that HTML is generated inside this function and it calls itself recursively. I'm not going to walk through these because we have a lot JavaScript to get through tonight but this is an example of some business logic that would be private from the client that is kept in a separate folder from the point of entry into your application. So this is how it looks without JavaScript. And the next version, we'll add some JavaScript so that it only shows the directories and then we'll be able to click into those directories and just see the files. So let me-- [ Typing ] -- go into 01. We'll go into 01 in here as well. If we go on to the HTML directory, now we see an HTML folder in a private underscore PHP folder and if we click that it expands and if we go into the HTML directory, this is the directory that's supposed to house of the world readable files. So we see we have a JavaScript folder. If I have styling in here, I would put it inside the CSS folder. If I had images, I would put it inside an image folder inside this public folder. I am going to change directory into JavaScript and look at main.js and-- [ Typing ] And inside the view I echo out the directory that the JavaScript is kept in and this is the style for including a JavaScript. David probably went over this in the lecture. You say script and then SRC equals and then the URL to the JavaScript file. The JavaScript file has to be chmoded 604 at least so that that last byte has that world readable permission. And for legacy reasons, we don't self-close this tag. Instead we close the script tag and then put a closing tag after it. That just ensures that it loads. And we know that this is loading because this functionality is here. So let's take a look at the JavaScript. [ Typing ] So we have one function, init php file tree and that function spans pretty much the entire document and then down at the bottom we have window.onload = init php file tree. So in this file, what we do is generate a function or declare a function and then set that function to be executed when the windows.onload handler files. So this evening we're going to talk about the document object model. The document object model is a model inside the browser of the page's content and the content of the document object model, you can think of it in your head like the HTML file. It's a hierarchy of parent-child nodes and it really just-- in the document object model, the HTML content is an object and the body section is another object and then each one of these objects has properties and the properties include placeholders for events to happen and one of the most important document objects is the window object, which is JavaScript's representation of the window that houses the web page and that window like many of these elements has an onload property that you are able to set equal to a function and if you set it equal to a function, then when the onload event occurs, in this case, when the window is loaded then whatever function is stored inside that onload property will be executed. And it's up to the browser manufacturer to make sure that that function, the onload function is-- the function stored in the onload property is called at the right time and you would have to look at the documentation of the DOM in order to find out what those properties are. Some other properties that various elements have are onclick and if you store a function inside an onclick property of the document object such as an A element then you can have that function executed when that A element is clicked. So if we go into this just a little bit more, we can see our second document object, this is the global document object, which is the object that represents the entire HTML document and it has a function getElementsByTagName. What that function does is make it so that you can get a list, technically an array of all of the list item elements. So what this is finding here is all of the li elements as an array. So now aMenus, the variable, has all of the list item elements and you will recall that we encoded all of these files as list items. So when we get all of the elements by tag name for list items, it's getting this item and this item and this item. If we press ctrl shift C in Chrome, you can see that this is a list item and this is a list item and now inside aMenus is an array of the document objects representing this node and this node and this node and this node. And every array has a property called length and you can iterate through it and you-- Another property that document objects have is the className property. The className property contains all of the class names. You'll see in here, here's a list item that has an attribute class = pft-file and also a class name equal to ext-php. So in this line, we can retrieve an array of all of the classes for the document object and if the class begins with pft directory, and this is something that's leveraging off of what the PHP function does. It creates a UL-- it creates an li element that is annotated PFT directory if it is the name of the directory. So that logic-- that data is encoded here into the HTML and we're able to extract that data with this statement. The index of command is a function that returns the index of a substring inside another string. So for instance, in the word string-- substring, index of string would be zero, 1, 2, 3 because this substring appears here starting at character three and it returns negative one if the substring is not found in the string. So what this is detecting is the following logic will only be executed if the class name begins with the directory. So now we're going to handle the directory and in the directory, we will get the child nodes. Here's another document object property. The child nodes document object property contains a reference to an array that contains all of the child nodes of the current node. So in this case, actually it would be easier on the screen, if you look here at the screen. List item class equals PFT directory, that is what-- inside this list item, the list item class equals PFT directory is aMenus underscore i and we're going to get the child nodes of this and as you can see how it indents, it's going to return an array of references to all of its direct children. And again, arrays have a length property. So you're able to iterate through until the end of the array. So when you're getting to know JavaScript and getting to know the document object, you'll pick up a few of these property names along the way, and then once you've learned a few you'll have a good handle on what API the document object model exposes to you. Here we get all of the sub menus with tag name equals A. Tag name is the actual name of the element, so here is an A element, an anchor element, and so now we're going to handle this anchor element and set the onclick property of that equal to a function. Now here is JavaScript we have an anonymous function. The function is declared right here inside the loop, you have function and that function goes all the way to here. Let me highlight it. That's the entire function that is then stored inside the onclick of the sub menu. And because in JavaScript functions are first class citizens there are-- functions are first class data in JavaScript, which means that they can be passed into a function, return from a function, in here we're storing a function inside of a variable and that variable is a property of whatever object is inside the array submenu[j]. So sub menu is a an array of objects. We have one of those objects currently in memory and we're putting inside a property of that object a function that would be executed at a particular time that is arranged by the browser and onclick happens when you click on it. And-- so I'm not going to go through all of the code line by line but basically, what that does is make it so that when you click on the files themselves it gives you an alert that actually tells you the name of the file itself. Inside each of these document objects, in this case it's an anchor object, there is an onclick property and inside each of those onclick properties this is a reference to this function. So I think we've kind of established the basic point here so let's retreat out a little bit. So, when you're writing JavaScript, it's important to be stylistically consistent. JavaScript is a language that was made in a hurry, it was made in a very short period of time during browser wars between Netscape and Internet Explorer. And the browsers were trying to one up each other and it was developed during a very short period of time. And so as a result there are lot of good things in JavaScript but there are also a lot of bad things, and the bad things are not useless but there are things that lead to dirty code. So at the beginning of the section I talked about these videos by Douglas Crockford. He is a JavaScript guru that was around at the time that JavaScript was first blossoming onto the stage and he was one of the early players in that space. And Douglas Crockford is I guess most famous for having invented and-- one could say maybe not invented but popularized the JSON JavaScript object notation data format that we're going to use later in this course. And Douglas Crocfkford is somebody whose program did a lot of languages and he understands a lot about the interaction between coding style and a predisposition for errors to creep into the code. And with that in mind he wrote this tool originally as a stylistic enforcer for writing good JavaScript code that would teach you and enforce in your own code these certain best practices with the JavaScript. Stuff that's written with JSLint doesn't necessarily run faster, it's just cleaner, easier to maintain and in general, more-- it tends to reduce the probability that bugs are difficult to see for predictable reasons. So its most often used online because it's a tool that's written in JavaScript. You can paste some JavaScript right into here and then lint it. In fact, if we go back into JavaScript and-- let's see of it opens up. So you copy it and here press JSLint then you'll see a list of all the stylistic things that you could have done differently but I highly encourage you to re-factor your code with this in order to learn from Douglas Crockford's experience. He is very idiosyncratic and he has a certain way that he likes things coded and that way is not necessarily the best way but he is somebody certainly who has a lot of experience in the space and it can't hurt a JavaScript developer to know about Douglas Crockford's highly influential style in the space. So you can certainly correct it here in the browser by pasting it into this display and then clicking JSLint or you can integrate it into your actual command line here. I've included some instructions here for installing it in the Impliance. Once you install it in the appliance then you can do a jslint main.js and it gives you those same errors that are right here at the command line. And because it's in such a predictable format and because people have been writing code on the command line for years, there is a syntax called error format that is used to help parse the output of thees linters. A linter is a tool that helps you analyze your code and see if you can improve certain things about it and it goes all the way back to C, there were linters for C. And in this case if you know the error format you can write a little script for Vim, the editor, that will read through the document and let you process it all in one place. So I'm going to copy main to main2.js and just open up that and because I have error format installed, I can press F4 and you can see it jumps to the first error which is on line 33 column 3 so I can go 33 capital G and then go to column 3, right here. It puts your cursor right there and it says missing use of use strict statement. So at this point if I was curios about what that meant I could say use strict JSLint and usually a Stack Overflow thing comes up and see 619 people have found this useful. And so basically, you have to put that phrase use strict somewhere in your code and you can read through here in order to figure out why the basic answer is that there are many different versions of JavaScript and for backwards compatibility reasons when they made new versions of JavaScript, they didn't want to deprecate certain features that were a bad idea because it would break the code. So if you do use script or use strict then it deprecates certain things and makes available ceratin things. And so let's go up here to the top and just put use strict and now I'm going to press F4 again. And that error has gone away and now we've moved on to the next one. It says, expected if at column 5 not column 5, oh, well E wants us to indent in a certain way, so I'm going to make it go now, you can see right here, I'm at column 5, not column 3, press F4 again, and it says document was used before it was defined, so again you could Google this, document used before defined JSLint. In general, when you have a global variable, global variables are very, very problematic in JavaScript because on one page, you can have not only the page authors JavaScript code array but maybe an ad running that is loaded dynamically through a content distribution network where the person who wrote the JavaScript doesn't even know what page it's running on and because there is the capability for global variables to exist in JavaScript, if you make an-- a variable called foo in your JS file and then in an ad.js file they, unbeknownst to you, also make a var foo then which ever one is located lower on the page when it's actually loaded will clover the earlier version of the variable. So this is very problematic in JavaScript. It's one of the not the good parts of JavaScript but one of the bad parts and to mitigate that, he wants us to acknowledge in the code that this is a global variable by putting in this global directive. Basically, what he's suggesting here is that every single global variable you should acknowledge that it is global and that it could be-- it could be clobbered. So, if I press F4 again, it says, document, let me see. Oh, yeah, you have to say global document, and it says document was used before was it defined so if I do var document then, now, we can go on. It says expected a left brace and instead saw a return, so here he's saying you need to insert a right brace and basically, what he's suggesting is that it's bad coding practice, do not use these braces with ifs because it lets bugs go into your code more easily. So, now it says, expected var at column 5 not column 3, I'll make it go to column 5, combine this with previous var statement. So, in JavaScript you can declare all your variables at once and then we're going to get-- it's-- the for is expected at column 5, so basically they want 1, 2, 3, 4 spaces for each indent and you can guess that this variable and this variable as well are also going to come up. We're going to need to insert I, M class, all of our variables here at the top. So, if you move all the way out and complete the cycle. [ Typing ] If I press F4 here, you can see it just returns. I'm completed with linting this and I've-- You can see that all the variables are defined at the top of the function. Here's a global document directive for the global document object. Here's another function and this one is pretty different, this is a pretty significant departure from the previous version. Let me just open that one up side by side. [ Typing ] So, before you'll note that we looped through and inside the loop, we declared an anonymous function that was put inside the onclick handler for, here it is, yeah. submenu[j].tagName = A then submenu[j].onclick = function. And then here's this huge function. Well, this is very problematic and it leads to bugs, especially with event handling, because we're storing separate function in every single element of that array even when JavaScript has the ability to store a function in an object like this, submenuOnclickFunc = function. And then here is that same code. It goes all the way down to there. And now, we began looping through. And now, it's reduced to one line, submenu[j].onclick = submenuOnclicklFunc. And not only does it make more readable like you'll notice that here it has to indent quite far in order to get through all that nested logic. But also it makes it, more importantly, it makes it more correct because when you're dealing with event handling functions, it's very important that you're only dealing with one function in memory and not creating a thousand functions. Each function has an instantiation cost so if you instantiate a thousand functions you have to do that each time. Also, there's no predictability about events. I could get into exotic examples that have to do with timed delays and maybe with things moving around but you'll have to take my word for it or watch his videos because he gives a good example of it as well. So, this is, in general, the way that he wants you to do it and it's a good idea. Declare all your variables at the top of the function. Then-- And then initialize each of your variables. Here one of our variables is a function that needs to be initialized with this function. And then go into the logic of the function itself. So at this point, I want to take a step back. And just run you through some slides from a presentation that Crockford made a few years ago. This is for YUI Theater. So we're just going to run through the quick syntax and some of the pitfalls and some of the examples of JavaScript. Again, this is by Douglas Crockford. These are his slides. He gets into a lot of really kind of esoteric examples that we will not get into here but these are some, you know, some bridge selections from some slides that he's done before. So, JavaScript has good parts. We'll get to them later. Right now, we're going to kind of talk about the bad parts which come from legacy, good intention and haste. Haste because it was developed really fast. And so with numbers, there's no integer types so immediately with the integer type-- if you're dealing things with money, you'll have to be aware that there's going to be some rounding because there's floating point math all over the place. Of course, it is 64-bit floating points so you can achieve a level of precision with it. But everything is based off of approximations. And that becomes problematic in certain points. For example, the associative law does not hold because of the slight bits of rounding that happen with the floating point representations of the numbers. So this actually produces false for some numbers of a, b, c even though mathematically it's not a false statement. So, decimal functions are approximate. That is actually false here. In JavaScript there is a math object and when we talk about objects in JavaScript we use dot notation in order to access the member methods. So in here you would do math.sqrt and then pass in parameters in order to get to the square root function. So be aware that if you want to use any of these functions, you have to prefix it with that math object names for the global variable and then the dot operator. And again, this is, you know, an example of how fragile the global name space is if some, you know, malicious JS were to override the math variable and replace it with its own contents. Maybe they could even manipulate your code if they knew that you were using and relying on those functions. So that's an example of how to call a math function. NaN, you'll see this inside of your debugging. This is-- this stands for Not a Number and it's the result of erroneous operations. So if you do a 1 divided by 0, then you'll get NaN. The-- it's toxic so any arithmetic operation with-- that produces this result will also have NaN as a result. So that means that if you add 1 to 1 divided by 0 then the result of that will also be NaN, not a number. But here are some other bad parts. NaN is not equals equals equals NaN which is very strange and even stranger, not a number is not equals equals NaN. So the difference here between equals equals equals and equals equals is that the first does not involve type coercion, it's strictly quality. But the second does allow type coercion and by type coercion I mean that you can in certain cases treat strings like numbers and in other cases you can treat them as strings. And we'll get into that a little bit later on. So in order to test equality with strings use equals equals equals plus can mean concatenate two strings or it can mean add. So here the string dollar sign plus the string 1 plus the string 2 equals the string dollar sign 1, 2. And it's equivalent to using the concat function. And here you'll see this string that's contained in these-- between these two singles quotes that is actually accessible as an object using the dot notation. And it has the concat function as a method of that object. Everything in functions or everything in object-- JavaScript is an object/function. So in order to convert a number to a string, you can call toString on the number because numbers are objects. There's this interesting operator, the plus, if you put plus in front of the string one like plus 1, then that actually turns this into the number one or if, sorry, if var contain-- if a variable contains a string and it's used with the plus operator, then you can coerce it into a number by using typecasting facilities. You can also use the parseInt, the global parseInt function, where you pass in a string, and then you specify the-- you specify the radix. Every string has a length property, this is much like arrays. Arrays have a length property as well. This contains a number that's equivalent to the length of the string. Extended characters are counted as two, so that means that if you have a Unicode character like umlaut u or something, then that will actually give you a count of two for one character if it's, you know, a multi-byte character. So for arrays, arrays inherit from objects, so arrays are also objects, they also have a length property, which allows you to look through them as we saw before. In order to do an array literal, you use the square brackets. This is much like some other languages. You have to put commas in between the different items, and then new items can be appended by doing the-- by including an L-- an index that's outside of the array. So the thing that's really kind of nefarious about arrays is that indexes are actually converted to strings and used as names for retrieving values. This is really strange. The-- You can run to some problems with it. It's not like a Java array or something where if you-- the-- if you remove an index from the middle of the array, you'll literally have an array with a hole in it because those are string keys to those values unlike, say, a Java array. So array methods have-- these are some array methods, and because these belong to the array object, you can have an array and a variable and then just call dot splice or dot slice or dot sort. So sort is very unusual because it defaults to alphabetical ordering. And in alphabetical ordering, this is actually the alphabetical ordering of these numbers, so be aware, and even if you put numbers in and you call sort, then they'll sort out of order unless you actually, you know, do sort and then pass in this function that returns a number that's either greater than zero, equal to zero, less than zero in order to indicate which is greater than which. So that's part of the bad elements I guess of JavaScript, the funky defaults. Here if you do delete-- delete is a keyword and if you say delete array and then three, in an array that's five indices long, then now you have a hole in the numbering and if you try to loop through it, you'll actually encounter an error at that point. But array.splice will remove the element or renumber all the following elements, which is pretty inefficient. So use objects when the names are arbitrary strings and use arrays when the names are sequential integers. They're very similar in JavaScript. In JavaScript, the simplest object is two curly braces, in JavaScript the simplest array is two square braces. And you can have objects that contain arrays, and you can have arrays that contain objects, as we'll see when we get into JSON in a little bit. Unlike a lot of languages, regular expressions, which is a special sub-language that's designed for searching strings, they're actually a type in JavaScript, and you actually indicate them with the slash on the end and the slash on the beginning. So you can literally say var foo equals slash star dot-- or dot-- or, no, php dot star slash and then semicolon. You don't have to put in strings like some other languages. So in JavaScript things aren't typeless, everything is loosely typed. But all of these values are kind of falsy. And so if you put each of these things inside of an if statement, it will not execute. And so these operators are equals and not equals. And they can do type coercion, which means that they can convert strings into numbers or vice versa based off of what JavaScript thinks is best. You can learn those intricate rules of when the type coercion happens or you can do like Douglas Crockford suggests and just use these all the time which do not use type coercion. And the reason why you should do that is because type coercion and JavaScript is evil because here is an empty string, == 0, that is false, but the number 0 zero == empty string is true, and even worse, the number 0 == the string 0 is also true. So this is totally bizarre. Type coercion is truly pretty weird and I ask you to please stay away from it by using the non-type coercing operators. So all values in JavaScript are objects except for null and undefined. Null is a value that isn't anything. And undefined is a value that isn't even anything. All right. It's so weird that they have both of these keywords, and it has to do with this structure of variable hoisting that happens in JavaScript. And undefined is basically the default values for all variables and parameters that haven't been assigned a value. And it's in fact a value of missing members and objects. So if I have, you know, var M equals the simplest object and then I want to access M.foo which hasn't been accessed-- declared yet. This is undefined at that moment, which is different than null because null is something that-- It's like-- funny to think of it this way, but it's actually a positive statement. It's saying, "This is not anything." And undefined just means it hasn't been defined yet. So I put this in because JavaScript also has a switch, a switch statement. So that's most of the bad parts. Getting on to functions. There are two ways of declaring functions in JavaScript. The-- There are function statements and function expressions. This describes function expressions. This little part right here is a function expression. This is what we saw before and when we declared a function anonymously and inserted it inside the onclick handler of that A element. Function expressions have the function keyword followed by an optional name and then, you know, maybe some parameters like x here is passed in as a parameter. Note that you don't have to do var x or string x, there's no type checking that's done, so you just name whatever variables you want to pass in. And then the body has to be wrapped in curly braces and contains zero or more statements. That's a function expression. A function expression produces an instance of a function object. So the result of this is that an instance of a function object is inserted into this variable at one. Function objects are first class, which means that they can be passed as an argument into a function. They can be returned from a function, they can be assigned to a variable like we did here, we assigned the function into-- to be stored inside that variable and it can be stored inside an object or array. That's what it means to be a first class entity in computer science. A function statement on the other hand is like this. So you have the function keyword and then you have this label for the function and these are something that you can do, but it's a little bit deceptive and Crockford recommends that you actually kind of move away from this and go more toward the expression syntax. And the reason why is because function foo, with no parameters, an empty body, expands to variable foo equals function foo with no parameters, no body. And this in itself expands to variable foo equals undefined and then foo equals function foo. So this is really just a long complicated way of performing a function expression like why didn't you just make a variable foo and store an anonymous function in it. It's a little bit deceptive to do it this way and it's really some syntactic sugar to help persuade people who use classical languages just like Java or C++ to, to use JavaScript. So when they say the assignment of the function is hoisted, this is one of the most misunderstood things about JavaScript and it's-- it can-- it'll really trick you up in your assignments if you're not aware of it going into it. Be aware that when you start to get some bugs that have to do with variables being assigned values and you don't understand why because it's inconsistent with PHP and C++ and Java and other languages that you've used, it's because in JavaScript we have function scope and not block scope. So here I just want to reinforce this one where you put an anonymous function inside a variable, that's a function expression. Here where you say function addOne this is the function statement. This is the one I don't want you to use. This is the one I do want you to use. So a var statement declares and initializes a variable within a function. A variable declared anywhere within a function is visible everywhere within the function. This is the thing that really tricks people up that come from other languages because if you have var x equals function and you have some code here, var x var y equals 2, var x equals 3. Var-- even though there's code here x is actually available inside this code because what happens behind the scenes is that this part moves all the way up to the beginning of the function and there's implicitly this var x, y and then you're left with y equals 2 and x equals 3 and X is actually valid as a variable inside all the entire body of the function and that includes functions that are nested within functions. So that's why Crockford recommends you declare all of the variables from the function right at the top because technically, that's what happens behind the scenes so why not make it more clear. So declaring a var, it just expands it out into two declarations where my var equals undefined and my other var equals undefined and then the initialization happens. So this function would work in Java, it would work in PHP, but in JavaScript it doesn't work because what happens is that there's not a new variable i here. There's only one variable i and it's hoisted up and declared right here and set to undefined and then it's overwritten. It'll let this-- this program will run forever. It will not terminate because i is not really declared here. So that's why you should always hoist your variables, you know, as a preventative measure. So declare all your variables at the top of the function and declare all functions before you call them. The language provides mechanisms that allow you to ignore this advice, but they are problematic. So this is also problematic so if you leave off a semicolon JavaScript will actually insert it for you automatically. If you are to leave a semicolon off here, JavaScript will be like, oh he meant semicolon, and semicolon means that that's the end of the statement. Unfortunately, the semicolon isn't always inserted in the right place and it isn't-- doesn't exactly do you want so you have to be really careful not to admit those semicolons. So besides variable hoisting the value of the this variable is probably the single most confusing thing about JavaScript. So this parameter contains a reference to the objects of invocation. What that means is that the object when it's actually invoked, when it's actually ran in the browser, this is-- the keyword this is very different depending on where it is instantiated. So in general this allows a method to know what object it is concerned with. And it allows a single function to serve as many functions. You know, it is really important. It's the key to making big structures. Things like Gmail wouldn't be possible without this keyword. As we saw at the very end of lecture the parentheses, suffix operators surrounding zero or more comma separator arguments will invocate whatever comes before it. And by invocate we mean execute. If a function is called with too many arguments the extra arguments are just thrown out. If a function is called with too few arguments the missing values will be centrally undefined because everything is set to undefined until it's a set of value in JavaScript. And there is no implicit type checking of the arguments like there is in Java. So there are few-- there are four ways to call a function. There's the function form where you have an actual function that you're evoking like-- let's say-- what's a good example. Well like any function that you define on your own in global scope. And there's the method form where you're actually calling it as-- it's called a method rather than a function because a method refers to an object that opens it or that it belongs to. A method is a function that has references to properties and variables that situate its context. So this is actually the most common names. So like math.sqrt is the method form. When this function-- when a function is called in the method form this is set to that big object. So inside the body of this function, of this keyword, it stands for the math object inside math.sqrt. And this allows methods to have a reference to the object of interest which is important because in the math object they might have lots of constants. They might have a constant called pi. In the function form the-- you-- like we thought anonymous functions then you have-- well, some anonymous functions. This keyword is actually set to the global object. And if you make-- a function is nested within a function then the inner function will actually have its own scope and its own this keyword. And so in order to get access to the outer functions variables you need to set-- in the outer function you need to set a variable that traps this variable and make it available. So let me explain what I mean. If you have-- [ Writing on Board ] Var outer = function. [ Writing on Board ] Var secret = 12345. Var-- [ Writing on Board ] So in-- actually this is. Let's say that the-- that this was-- let's say that we're talking about the onclick handler before. a.onclick equals function x. This element here contains a reference to that A document object in this scope. However, here this variable contains a reference to this function. So in order to get access to the A document object you need to say var that = this and then inside here you can say that.classNames, you know, you can perform operations on that anchor document object inside of this function by making sure that this local scope doesn't clobber this variable, this keyword that you need access to. So this chart is really the key to understanding it. If it's called like math.sqrt then inside that this object contains a reference to the math object. If it's called in a function format like where you just call the name of the function then this actually contains a reference to the global object or it's undefined depending on the version of the JavaScript. If you instantiate a function using the new keyword then you actually get inside this object the new object. And we won't talk about apply. But this can actually change a lot about the way that JavaScript is done. So let me just say a thing about closure and then we'll talk jQuery really fast. So the context of an inner function includes the scope of the outer function. In this function that's inner you are also inside the scope of the outer. So if we had a var foo here you'd be able to reference foo inside this function. The inner function enjoys that context even after the parent functions have returned. So that means that if this function is executed, let's say the onclick happens but do something as a function that occurs much later, much, much after the onclick event. Then variables that were in this outer scope are still available to this function even in that much later timeframe. And that's key because this function closes over this function and makes it possible so that even when a function is like kind of deposed, it's not deposed but when it goes away and will never be instantiated again. If there's a function that can be called within it then you are able to get access to any of the variables that were declared in the scope around it. This is the power of JavaScript. This is like one of the best things about it. It's a quality that it gets from Lisp. And if you go through the videos you can see the language hierarchy and how it derives from Lisp and other languages with closure. So here is a way to do a function that uses global scope. So this is a function that takes a number and returns the name of the number. You pass in nine and you get out the string nine. And names here is accessible inside this function because you have global scope. So alert digit name three will actually pronounce the word three. So that's global scope. Here's a way to do that inside a function that's really slow. You declare function with a large array in it and then you return the names value and it's slow because every single time you call the function it allocates memory for this array, again, which is a waste. In closure what happens is that here you see this parenthesis and this parenthesis. They're not required but these two parentheses that are after the function, they are invoking this function immediately after it's declared. And he's put these extra parentheses around here. We're going to call attention to something special that's going on. What's happening here is that he makes an anonymous function and then instantly instantiates it. And so the function is gone after it's instantiated. And the result of it being instantiated is that what's stored inside digit name is a function and that function itself has access to this variable that is stored in that scope, that's closed over it. So this gets declared once in memory and even though that function has closed after this variable digit name has been initialized, even though that function is closed those variables are accessible to this function that's then stored inside digit name because it's returned as a first class object. So this is the special thing about closure. And it enables you to do things like this. So here you have a variable dom which stands for an element that you called getElementById if you know that you have like div id = 327 then you can say document.getElementById 327 and it will return a reference to this div element in dom, in the document object model. And then it also makes a variable level equal to one. And these are variables that will be available after this function has been executed. And inside of this function he makes a function called step that basically set this function, setTimeout is something that is available in JavaScript. You pass in a function and then a number of milliseconds for it to wait before executing it again. And it only executes it once. But here the step function says call me 100 milliseconds later and level, up here, it's set to 1 and level is incremented by 1. And it says if level is less than 15 then execute it100 milliseconds later. And so h here is set to the string of the level amount. So it's 1, 2, 3, 4, 5 and it's set in toString in base 16, I believe. Yeah, I think it must be in base 16. And then they're able to actually-- FFFF is for r and g and then the h and h will actually be the blue code. And so they're setting the background color of the element to be an ever lighter and lighter blue value. It starts out pretty dark and then it gets lighter and lighter until it becomes FFFF. And because this level variable is available to this step function even after this function has closed then what happens is that when you call fade id then it will fade really gradually over, you know, 16 steps to white. That's the kind of thing that closure let's you do. So the jQuery is a library that operates on the principle of that you can store an object inside a variable with a name that's a single character. And in jQuery that character is the $, so in jQuery which is a library that you have to load any time you put the $ you can then put a dot and then call a function name that is built in to that library. So let's take a look at the jQuery version of the same PHP directory. And you can see we have a nice sliding effect. And it has the same kind of thing but now it slides up and slides down. And the sliding facility is probably done with closure just in the fade manner that we were talking about using set time out. So let's take a look at the code. [ Typing ] First of all, I'll look at the view. Oops. [ Typing ] So I highly recommend that you are able to go to the jQuery site and download a file called jquery.js and then include it in your JavaScript directory and include it just the same way you'd include your own JavaScript. You can do that. However, there are several advantages to doing it this way. Google offers as a service-- [ Typing ] -- these libraries, there are several of them. It's not just jQuery. There's Dojo, MooTools, Prototype. And if you look down at jQuery they give you this nice path. And if you do the .min.js1, that's the minimized version so it will be a very small amount of code. And the advantage to having Google do this is that there are a number of servers distributed throughout the country that Google maintains. And because JavaScript files are public files you-- and if you hit it once then you hit it again within the caching period of your browser. It actually will download it from the closer server than from the farther server and also, it will download it onto your own machine if it's from the same domain. So the idea is that Google is so common and people Google it-- Google things all the time that if everyone uses the same source for jQuery it will result in faster response time for everyone and they're very kind to do these things. It's kind but also they get something out of it too because they're able to get demographics about who's using each of the libraries and make decisions based off of that. So this is all it takes to include jQuery. Now let's take a look at the actual script itself. You can see it's a lot smaller. This is the entire code required to do the same thing. Here you'll see the $ object. Every, you know, every object is a function sort of passing into the dollar-- the $ variable contains a function that can be invoked with the parameter. And if we pass in the document the variable containing the document object then we'll-- it will return a value that's accessible via a dot operator here that we'll be able to actually call a ready function on. So what this first line does is this gets called only when the entire document is ready forff JavaScript to operate on it. Basically, when the entire document object of the page has finish flowing out then it calls this anonymous function inside here. And one of the notable things about jQuery is that you can use what's called CSS selectors. So if you go inside here you'll see PFT directory and pft file tree or class. On CSS you select a class with dot and then the name. So selecting .pHpFileTree selects every object with the class equal to pHpFileTree. And then it returns that jQuery object with that array of document objects inside of it and because it's a jQuery object that's returned you can continue to call jQuery methods on it such as find within that array UL items. And UL items are like this. And, you know, if you had a nest-- deep nested structure you'd have more UL items. And you'd hide them. So if I restart this that's this very first thing, it hides all of the subdirectories that are represented by UL elements. And then it finds all of the A elements that are children of elements that have a class of PFT directory. And it registers an event that happens when you click it equal to this anonymous function. And this is great. You can find the parent of the object that is clicked on. This contains a reference to the object in question. In this case the document object that represents the thing clicked on. So when I click on this, this variable actually contains the document object model for that element right there. And within it, it finds the CSS selector UL colon first is the very first unordered list. And jQuery is this nice method, slide toggle with adjustable speed that basically unfurls the children elements. And so jQuery has a great documentation. You can see that one of the parameters you can pass in is the duration and another one is callback. You could pass in a function that it would execute when the slide is done. And the slide they're talking about is that slide right there. And you can even see how it uses overflow equals hit in and then the height equal to these floating numbers and it adjusts it, you know, using a millisecond delay in order to make it look like it's unfurling. And then like it's sliding open. And basically if the attribute of the parent is PFT directory then you return false. I mean that's the entire functionality. All of the clicking functionality is put in there by the PHP actually. So that's not provided by the jQuery. jQuery is very, you know, very easy to get advanced functionality. And the functioning you're probably using most often in coming assignments is JSON or AJAX. JSON is actually an alias to the AJAX method in jQuery. JavaScript objects notation is-- oh, we just barely didn't get to that slide. Let's get to it. So this is the syntax of JavaScript object notation. You can have brackets and within brackets you can have a value separated optionally by a comma. And a value can be a string, number, object, array, true, false, or null. And so, you can encapsulate an entire JavaScript object with this syntax. And in fact the function parameters here, you know, they follow this JavaScript object notation itself. And so, JavaScript object notation is in data interchange format and there is a great JSON encode function in PHP that takes an array or an object like here's an associative array where the letter A goes to one, the letter B goes to two, so on and so forth. And it says JSON encode array and that returns an object with these curly brackets here. And you see the string A has a colon and then value one and then a comma. And so this is an object with the parameter A equal to 1 or parameter B equal to 2. Because this function exists and is supported in PHP we're able to construct an entire data structure and then call JSON encode and then actually embedded in our JavaScript, and embedded in our JavaScript programatically before it is actually received by the recipient. And in order to see an example of that-- We'll get into this more next week with AJAX, but for this week I've included some examples from last year. Open cycle map, this is just a simple example where this is a tile from a map that has a certain name representing its latitude and a certain or a certain number representing its latitude and a certain number representing its longitude. And when you call or when you hit these buttons then if you're listening on the network you can see that when you go west it calls the URL with these functions. You can see zoom equals 15 and x equals 9910 and y equals 1211. And the result is it returns the directory of-- or it returns the file name of this image. And the-- you can assemble a very large amount of data and then actually echo it inside the header of your document and evaluate it in JavaScript in order to pass that data directly into JavaScript and be able to access it with the dot syntax you're used to for the objects. So that will be more for next week because it has more to do with AJAX. But feel free to play around with these examples. You can see how it goes north and south and east and west. And each time this downloads it will be impolite to hit the tile server that serves these up more than once. So actually what it does is it downloads the appropriate tile, caches it in a folder on the server and then subsequent hits to that image are restored from the cache. So you'll notice if I go north and south and then north and then north takes a little bit longer. And now if I go south and north it's nice and fast again that's because now it's cached on the server. And this is a style that you'll be using in the upcoming assignment because you'll have to be getting certain information about companies from CS75 finance, caching it on your server and not hitting that external API more than you need to. So I thank you for your attention. This has been a lot of stuff. I highly encourage you to use JSLint and to watch some of the Crockford videos. If you were to just to watch two videos or if you were to just watch one video, watch Function the Ultimate and skip through all the parts where it seems like you're not understanding anyway. And if you were to watch two videos watch these two. And they're basically kind of an overview of the syntax, the good parts, the bad parts, and what you can do with closure. So I thank you for your attention and let us know at the CS50 Discuss if you have any questions. And if you have any questions about my code in particular, feel free to email me personally. [ Silence ]