Placeholder Image

字幕列表 影片播放

  • [MUSIC PLAYING]

  • DAVID J. MALAN: All right.

  • This is CS50 and this is lecture 11, so the end is actually quite near.

  • And among the goals for today, and next time, and our final lecture time

  • together, is to start to tie things together as far back as week zero.

  • And in that spirit, I thought we would begin by reflecting on this clip here,

  • which you may recall from a few weeks ago,

  • wherein we tried to look in popular media at the perception

  • that viewers might have of technology, if they relied only

  • on shows like this, and on CSI, and the like, where what you see on the screen

  • isn't really technically accurate.

  • And this is wonderful to say, but most recently did Stranger Things

  • 2 come out, which most of you are probably familiar, and probably

  • finished, if you're like me, on Saturday after it came out on Friday.

  • And on the screen--

  • let me say this, not a spoiler--

  • but I was so proud of this particular show.

  • But before we get there, allow us to tease you

  • with CS50's own take on that same show.

  • If we could dim the lights.

  • [STRANGER THINGS THEME PLAYING]

  • OK, so that was mostly just a set up for the following,

  • and if you haven't seen Stranger Things, or at least all of the episodes,

  • I really don't want to alienate the entire internet,

  • let alone everyone in this room, just close your eyes briefly,

  • this isn't really a spoiler, it's all technical, doesn't spoil any plot,

  • but no one is going to care in a few weeks time,

  • so we thought we'd reveal this.

  • So now's the time to put your fingers in your ears

  • and close your eyes if you don't want to know that, at some point in the show,

  • there's this scene, here.

  • And of course, in every show out there like CSI and Law

  • and Order and the like, if you kind of zoom in and enhance the screen,

  • it's just nonsense, like a crayon type program, like we saw from CSI.

  • But I was so proud to see that, if you actually zoom in on this screen here,

  • you see this code, in a language called Visual Basic.

  • And even though we don't teach Visual Basic,

  • nor do many people use Visual Basic as much anymore,

  • can you glean what this programmer was doing on the screen?

  • What seems to be going on?

  • AUDIENCE: Is it like getting a four digit password or cracking--

  • DAVID J. MALAN: Yeah, it was a program with which

  • to crack a four digit password.

  • And if you glean all of the various loops in this structure,

  • you'll actually see that it's trying to come up with a digit after digit

  • after digit after digit, trying all of them,

  • until finally, when it finds that value, something interesting happens.

  • And so now, those of you who have your eyes closed and can hear this,

  • you can take your fingers out of your ears and we'll proceed.

  • But perhaps the first example in media of an actual program

  • that works on the screen.

  • So now, today, we look back on a model we've

  • been introducing for some time, MVC, model, view, controller, which is just

  • a fancy way of describing a type of programming that's

  • really popular in the web these days, whereby you have a controller, which

  • is the code that you've been writing, in Pset 6,

  • and now Pset 7, in application.pi.

  • The fact that it's called application.pi is just a convention in flask,

  • but that's where all of your logic goes.

  • Like the code that actually drives your website.

  • In what folder or files are your so-called views?

  • Say again?

  • AUDIENCE: HTML?

  • DAVID J. MALAN: Yeah, the HTML file.

  • So in the templates subdirectory, which is a flask thing also,

  • you have a bunch of HTML files, which are

  • the views, the aesthetics, or the presentation of your program's

  • information.

  • And then last week, did we introduce, finally, the model, the M in MVC,

  • which represents your data, your database.

  • Maybe it's a CSV file, maybe it's in API, for getting stock quotes,

  • maybe it is a persistent database, wherein you store your users

  • and stock portfolios and more.

  • And together, these three entities compose

  • a pretty interesting application, whether it is a Pset 6 or Pset 7

  • or beyond.

  • But today, what we'll do is introduce one more piece and one more language.

  • I know we've discovered quite a few languages thus far,

  • Scratch, and C, and Python, and SQL, not to mention HTML and CSS.

  • But today, we introduce the last of our languages in CS50, JavaScript.

  • And you'll see that JavaScript is the last of the enabling technologies that

  • will allow you to build features and tools very familiar to you

  • nowadays on your phones and on your laptops.

  • And so, before we do that, let me go ahead and pull up

  • one example, via which we can bridge last week

  • and this, a final look at the Frosh IMs website from yesteryear.

  • And let me go ahead and run this program as follows.

  • Flask: run.

  • This is Fosh IMs 4, available in today's distribution code.

  • And if I go ahead and open up this URL, it's a very simple program,

  • that I'll zoom in on, that allows the users the ability

  • to register and to see who is registered and to register themselves.

  • And if I want to go ahead here and register,

  • I'm going to see a form like this, and I can choose from the dropdown

  • my Harvard dormitory, and then actually register my name.

  • And then in very first version of this, weeks ago, this program did nothing.

  • We just threw the information away.

  • Then we did something a little more interesting,

  • whereby we saved the data to someone's email inbox,

  • by just sending them an email, then we added CSV files, which weren't bad,

  • but what are downsides of using just CSV text files?

  • AUDIENCE: They take a long time to search.

  • DAVID J. MALAN: Yeah, they could take a long time to search,

  • because, especially as they grow longer and longer, the best you can do

  • is linear.

  • You have to search the whole file just to find one value

  • because there's no data structure there, it really

  • is just like an array of lines, if you will, a list of text

  • that you have to search over.

  • So we also don't have features like select and insert and delete,

  • these verbs, or operators, that we actually got from a database

  • last week, which allows us to do more work, more easily, without having

  • to write as much code.

  • We can literally just execute a SQL command,

  • like select or insert or delete, update or the like.

  • So, how might we go about building a piece like this?

  • Well, recall, that if we go into the source code for Frosh IMs 4,

  • we'd have some entry point, like application.pi,

  • and a few different routes.

  • And this might be familiar if you've dived already into CS50 finance,

  • the first of these routes, up top though, just renders index.HTML,

  • and that's where I see the menu.

  • And odds are, an index.HTML is just that bulleted list

  • of three options, each of which links to a different route.

  • Then the routes do start to get a little more interesting.

  • And on the screen here, on line 13 downward,

  • is the logic, my controller code, so to speak,

  • that allows me to insert a user into my database.

  • And how do I do this?

  • Well, on lines 15 and 16, I ask the question.

  • If the requests method that's just come in is get, what do I do?

  • In English?

  • Put up the register template.

  • So show the user register.HTML, using the using

  • the render template function, which we've

  • used before to spit out HTML files.

  • Else, if the user has used post, that is,

  • he or she has clicked a button, presumably, and posted to this same end

  • point, let's just distinguish the behavior.

  • If they've submitted a form

  • via post, then go ahead and execute these five lines here.

  • And this line here, 18, if not request, or if not request of name and dorm,

  • that was just a way of saying if the user forgot to give us his or her dorm

  • or name, then render a failure message, such as that and failure.HTML.

  • Otherwise, if he or she did give us the information,

  • we can use CS50's execute method on this DV variable, which we declared up here,

  • we can insert into the registrants a name and dorm's, specifically these two

  • values, and then recall that this colon syntax was new.

  • It's just a convention, in a lot of the SQL world,

  • when you want to plug-in values, rather than

  • use PercentS, back from our C days, rather than use curly

  • braces from our Python F string days, you instead

  • just pass on two values via these names like name and dorm.

  • And then what happens here, exactly?

  • If I go into this web site, and I register David

  • from St. Matthews, and click register, because the application is

  • running with flask, I'm told that I'm registered.

  • And how can I prove as much?

  • Well, let me go ahead and open up another terminal

  • and go into today's source code Frosh IMs 4, and then if I type LS,

  • notice that this is what composes this application.

  • One of these files is Frosh IMs.db, and if I go ahead and run this command line

  • tool, SQL light, 3 on [? Frosh IMs ?] db.

  • I just got a command line interface.

  • And you might not be comfortable with this approach, and that's fine,

  • but it allows you to do very simple things like show me my schema.

  • And I can see, from this textual interface, what the format is

  • of that database, it's just got one table, called registrants,

  • and then if I wanted to see who is registered,

  • maybe besides me, what can I type in this command line interface?

  • What can I type here?

  • Yeah?

  • AUDIENCE: Select star from registrants.

  • DAVID J. MALAN: Yeah, select star from registrants,

  • semi-colon, and I see a very text-based table

  • showing me who is in the database.

  • And thus far, it's just me.

  • And I could tinker with this at the command line,

  • I could update and delete, and so forth, but the key takeaway from last time,

  • was that once you're a little bit comfortable with SQL,

  • you can begin to use statements in SQL, put them

  • between double quotes in Python, and have Python execute those SQL

  • queries for you on your database.

  • And meanwhile, let's glimpse at one other feature here.

  • Before I registered a moment ago, I had this dropdown menu.

  • And I could have hardcoded this, and that would certainly be fine.

  • But if I wanted to actually delete a user and, actually, let

  • me show you this here.

  • If I go into, what files is that, that's in my templates directory.

  • And so if I go to register.HTML, here, I hardcoded

  • all of those dormitories that are available to Harvard students

  • to register from.

  • But what about my unregister page?

  • Let me actually go back and click unregister,

  • and you'll actually see here, I see kind of a prettier menu

  • that's got the person's name and their dorm, if he or she is registered.

  • And I somehow want to unregister the user.

  • Well, if I go ahead and submit this form, what value might

  • I want the browser to submit from the browser to the server?

  • David?

  • Matthews?

  • David from Matthews?

  • Something else?

  • What should your instincts be for when you submit something from a form

  • to a server, when you want to act on that data,

  • like here, like unregistering the user?

  • What do you think?

  • AUDIENCE: ID number?

  • DAVID J. MALAN: Yeah, maybe their ID number.

  • So, why?

  • I have this string, David from Matthews, why not

  • just submit the string, David from Matthews, look for it in my database

  • and then delete David from Matthews?

  • AUDIENCE: There could be other Davids in Matthews.

  • DAVID J. MALAN: Yeah, there's ambiguity, potentially.

  • If there's a couple or more Davids from Matthews,

  • coincdentally, you might end up unregistering all of them,

  • or both of them, or however many they have.

  • And so you want something primary to identify users.

  • And primary is an allusion to primary keys, which we said last time,

  • is generally a number, such as the number one, which we saw a moment ago.

  • When I looked at the contents of this database just a moment ago,

  • notice that David did indeed have the unique ID, one, or at least

  • we would see that it's unique if we keep adding

  • more and more users to the database.

  • And so how did I go about generating this?

  • Well, if I go to unregister.HTML, notice that I

  • do have to use a bit of one other language,

  • it's not a particularly fancy language, but it's

  • called Jinja, the templating language.

  • And notice what I did here.

  • This is the form, unregister.HTML, that the user sees

  • when I'm trying to unregister someone.

  • I have a form whose action is unregister, the method here is post,

  • and then I have the select menu.

  • Select Name equals quote/unquote ID, because I

  • want to make clear to the server that the value it's going to receive

  • is called ID, and it's going to be a number, like one or two or three.

  • And then this is how, now, I iterate over what?

  • What am I doing in line 6 and 8 and 9?

  • What's going on there in kind of English terms?

  • AUDIENCE: Number of registrants in your SQL.

  • DAVID J. MALAN: Yeah, I'm iterating over the number of registrants

  • I have in my SQL database.

  • Well, it looks like, and I'm just inferring,

  • it looks like I have access to some registrants variable,

  • more on that in just a moment, for registering in registrants,

  • the syntax we've seen before in Python that just

  • lets you iterate over things in a list.

  • And even though this is technically Jinja, it uses some similar syntax.

  • And what do I want to do on each iteration of 4 loop,

  • as I iterate over David and Maria and Brian and Rob

  • and whoever else is registered for Frosh IMs For each of those students,

  • I want to output open bracket option value equals quote/unquote,

  • and this is a bit of a mouthful, but this just says,

  • output the current registrant's ID number,

  • and the double curly braces is Jinja's way of saying, take that actual value

  • and plug it in between those quotes.

  • Meanwhile, recall that an option in a dropdown menu

  • has two parts, its value and then the thing that's

  • between its open tag and its closed tag.

  • So what I want the user to see here is quote/unquote registrant.name

  • from, literally, regristrant.dorm.

  • And that was just a design decision.

  • And it's that reason, for that reason, that the format of this list

  • is exactly that.

  • So and so from such and such a place.

  • And so the key insight via which you can make that happen

  • in application.pi, realize, is this.

  • When I visit "/unregister" via "get," which is the default if you just visit

  • the URL, notice that I'm executing a SELECT,

  • just like you proposed a bit ago, SELECT star FROM registrants.

  • But this time, rather than just seeing it on the screen,

  • I want to do something with it.

  • So I take these rows that are returned from the execute method

  • and I just pass them in to this template.

  • And I could call it anything I want.

  • I could have called it rows or x or y or z.

  • But I called it, a little more conceptually,

  • registrants equals those rows.

  • So I'm essentially handing to the template every row from that database

  • table.

  • And in this way in Pset 7, if you haven't already,

  • can you begin to construct the most dynamic of databases

  • and the most dynamic of websites, taking input from the user,

  • saving it, as we did when I registered, even deleting it or updating it

  • by programmatically generating content.

  • And this is the difference between a static website,

  • where if you look at it, every day it looks the same.

  • Because someone literally typed it out, hard coded, and saved it forever

  • versus a dynamic website, like Gmail and Facebook and the like,

  • that are obviously continually changing with more and more content.

  • And so underneath the hood of Facebook and Gmail and other apps

  • are databases like something SQL based, using languages

  • like Python and/or JavaScript and more.

  • And so we'll begin to see what other features we can now

  • add to these kinds of websites.

  • But any questions at this point on that sort of model for creating a web based

  • application?

  • Anything at all?

  • Yeah.

  • AUDIENCE: How again does a program know whether a request was

  • submitted via get or post?

  • DAVID J. MALAN: Good question.

  • How does the program, application.pi, know whether a request came in

  • via get or post?

  • Where is that information stored or available?

  • Does someone recall?

  • I keep forgetting to bring one more of these props.

  • But recall that virtual envelope, oh, here's one more,

  • so recall that when a browser sends a request,

  • we sort of played along by saying, oh, well, it

  • puts a request inside of this envelope like get me the home page.

  • Or here is a photo or here is my name that I'm uploading to the site.

  • There is literally a message in here, an HTTP

  • message that says the word "get" or "post," literally as its first line.

  • And so the moment the server sees that message inside the so-called envelope

  • does it know if it was get or post.

  • And realize, this is just me being a little sort of tidy.

  • There is no reason that we couldn't define two routes like this.

  • We could, in Flask, have one route called

  • register_form whose sole purpose in life is to show the user the register form.

  • So literally, the only thing it would do, is let's see, def register_form,

  • and it could literally return render_template("register.html") Right?

  • It can just blindly assume that if the user visits register form,

  • he or she got there by via get, the default.

  • And then, we could have that user submit elsewhere

  • if the route is actually register.

  • The method for which, because you have to explicitly say post

  • if it's not the default for you.

  • And then I say def actually_register.

  • Here, I could now have all of my database code

  • that assumes that only if the user has hit this endpoint has he

  • or she submitted the form.

  • And then I put all of my database related code there.

  • I point out that I'm just kind of being a little tidy or a little anal

  • when it comes to designing this.

  • Because I just don't like the idea of having

  • like this end point and this thing.

  • It's just two separate things to think about.

  • And also what the user sees is not pretty, as pretty of a URL.

  • It's not just /register, which makes a little more sense.

  • And so intuitively, this way, can we have the user stay constantly

  • at /register.

  • But the website behaves a little differently.

  • If the request comes in by a GET, show the user something, else,

  • if he or she has submitted a form, go ahead and do the database thing.

  • So that's all.

  • It's just me kind of compacting two separate routes into one just

  • to keep things tighter.

  • Good question.

  • Other questions?

  • All right, so let's now transition to a new world altogether of JavaScript.

  • And even though it might feel a little overwhelming,

  • to date, that we've looked at yet another language already,

  • realize that the important takeaways today are actually relatively few.

  • We're going to see some familiar syntax.

  • But there's a lot of shared features like functions and loops and conditions

  • and variables.

  • All of those are present in the same language.

  • And syntactically, it's very, very similar to C and Python.

  • So that's one takeaway.

  • And two, it's going to allow us to explore really

  • a different type of programming.

  • Because consider what we've done thus far.

  • When we wrote programs in C, we just started writing like #include.

  • And then we had int main and so forth.

  • And we just wrote our programs top to bottom.

  • We compiled them.

  • And then we ran them.

  • And they executed, essentially, top to bottom, so to speak.

  • We started doing that in Python, too.

  • In Pset six, you might recall the compare program or the score program.

  • Those, too, you just wrote Python code, top to bottom,

  • and then executed those programs.

  • But then we started doing something a little different with Flask.

  • In Flask, application.pi, when you run it indirectly by typing flask run,

  • does it ever quit?

  • No, I mean, you see some funky output on the screen,

  • like some IP addresses and all of the requests that are coming in.

  • But essentially you see a prompt that never goes away.

  • Because essentially, built into Flask, like any web server,

  • is really an infinite loop.

  • It's not a bug.

  • It's a feature whereby the program, once running,

  • is just constantly listening for HTTP requests.

  • And any time your application.pi gets an HTTP request, how does

  • it know what to do with it?

  • There is no main function.

  • So if it's just sitting there waiting and waiting for requests to come in.

  • How does application.pi know what to do and when?

  • Like what's been going on all this time?

  • AUDIENCE: By comparing the endpoints.

  • DAVID J. MALAN: Yeah, that's it, just comparing the endpoints.

  • So inside of this envelope that I keep grabbing

  • is a request for a certain page.

  • It's get/register or post/register or the like.

  • So as soon as application.pi or specifically, Flask,

  • the framework we are building our application on, notices, oh,

  • I see /register.

  • Let me see if the programmer has defined a route for /register using

  • our "at" syntax, @app.route.

  • Then, oh, that's the function that he or she presumably wants me to call,

  • upon getting that specific request.

  • And it satisfies it by returning some value.

  • But then it goes back to just listening in this infinite loop.

  • And so this is an example of what we might call event based programming.

  • You're not just writing a program top to bottom that just starts and stops.

  • You're writing a program that's just now always running unless you forcibly

  • kill it by hitting control-c or restarting the IDE

  • or something dramatic like that.

  • Otherwise, it's just constantly running.

  • But the events that might come in are a receipt of messages

  • or HTTP requests like these.

  • And similarly, in a browser, it turns out

  • there are bunches of different types of events

  • that can happen, not on the internet per se, but just locally, here.

  • Like, every time I click my trackpad or mouse, that's an event, click.

  • Every time I touch the trackpad or move my mouse,

  • that's an event, a drag event or a mouse move event.

  • Anytime I click somewhere on the screen or select something

  • from a menu or type in keys to my keyboard, that is an event.

  • So what we're going to start to do today is wrap up

  • the last of our user interfaces.

  • The past few weeks, we focused on the server.

  • Today and next week we'll focus on the client, the browser.

  • And together then you can have two pieces of the puzzle

  • finally talking to one another, listening for user input on the browser

  • and doing something with the user's input on the server.

  • So let's make that transition.

  • We began with Scratch, of course.

  • We transitioned to C and then Python and then SQL,

  • which was a little different syntactically, certainly.

  • But it did allow us to get data and update data.

  • But today we'll focus on this JavaScript.

  • What is the relationship, technically, between JavaScript, today's focus,

  • and the language some of you might have learned in high school, especially,

  • called Java?

  • Yeah.

  • AUDIENCE: It's like [INAUDIBLE]

  • DAVID J. MALAN: It's like what?

  • AUDIENCE: [INAUDIBLE] It's totally different.

  • DAVID J. MALAN: Totally different, exactly.

  • It was really just a marketing thing.

  • Java was very much in vogue at the time.

  • JavaScript was a new language.

  • And hey, why don't we name our language after something else that's

  • already pretty popular and kind of ride that wave.

  • But they are not the same language.

  • If you know Java, you know Java.

  • If you know JavaScript, you know JavaScript.

  • Syntactically, they're similar.

  • But there's no fundamental linkage between the two languages.

  • JavaScript is a language, now, that has historically

  • been used in the confines of a browser.

  • Which is to say, your Mac or PC executes this language in your Mac or PC.

  • However, it can be used and it's increasingly

  • being used on the server, as well in something called node.js.

  • But we're going to focus today and here on out on its use within the browser.

  • So fortunately, it's not all that different from Python or even C.

  • Here is an excerpt from a function in JavaScript.

  • What's familiar?

  • Well, we have the keyword function, which we have in Python.

  • We have some open parentheses, which we have in Python.

  • We have comma-separated lists of arguments,

  • which we have in Python as well as in C. Curly

  • braces, which we have in C, but not so much in the same way in Python.

  • And so it looks like it's kind of an amalgam of some of the features

  • we've seen thus far.

  • Indentation doesn't strictly matter.

  • So now you're sort of on your own again, such that good style

  • means that you have to be indenting proactively and not waiting

  • for the interpreter to yell at you.

  • But notice this, this is also legitimate in JavaScript.

  • And what just happened?

  • Before.

  • After.

  • What is this second version apparently lacking?

  • AUDIENCE: A name.

  • DAVID J. MALAN: A name.

  • And it turns out, in JavaScript, you can have,

  • and it's a very common thing to have, anonymous functions, functions that

  • have no name explicitly, otherwise known fancily as lambda functions.

  • And they, literally, just have no name.

  • Now, why that's useful, we'll soon see.

  • But just realize, that's going to be a feature that's also present,

  • technically, in Java and can be implemented in other ways in C.

  • But it's very much a common paradigm in JavaScript.

  • So getting comfortable just with the idea of your functions having no name

  • will be a takeaway for today, as well.

  • Variables, you'll notice this.

  • And you can perhaps infer what this does in English, even if you've never

  • seen JavaScript before right now.

  • What does this probably do?

  • Say again?

  • AUDIENCE: It's defining a variable.

  • DAVID J. MALAN: Yeah, it's defining a variable called i

  • assigning it equal to 0.

  • And maybe for the first time it reads nicely.

  • Let i equals 0.

  • That's kind of wonderfully stated, because that's

  • exactly what you want it to do.

  • What is missing though, from this line of code that we did have in C?

  • Data types.

  • So there's no mention of int or float or strings or so forth, explicitly.

  • JavaScript does have types.

  • But it, too, is loosely typed as is Python.

  • Whereby, there are types, but you don't have to explicitly mention them.

  • It's very context sensitive.

  • And the computer essentially figures out what

  • data type is what from its context.

  • But we'll have Boolean expressions again,

  • such as asking the question is i less than 50, or more generally,

  • is x less than y, where each of those might be variables.

  • Here is the do while loop.

  • If you've been missing that in Python, well, it's back in JavaScript.

  • And we can do something here.

  • And another little thing to notice, do you capitalize

  • or not capitalize "true" in JavaScript?

  • Apparently you don't, based on for inference.

  • And so it's these kinds of little things that,

  • honestly, early on, might trip you up.

  • And it's fine to get frustrated over it.

  • But don't get discouraged fundamentally by those kinds of nuances.

  • It's just like if you know two romance languages or two Asian languages

  • and you occasionally confuse a character or a word.

  • That will happen inevitably, now, in programming as well.

  • Here is a while loop, an infinite while loop in JavaScript, as well.

  • Here is a for loop.

  • Notice that it's almost identical to what we've seen in C,

  • except the lack of a specific data type.

  • I'm instead just declaring i implicitly to be an int in this case.

  • And this will get a little more interesting.

  • We have similar syntax in Python.

  • And it's almost the same in JavaScript.

  • If you want to iterate over the values of an array,

  • you can literally say let value, where this can be a variable x or y or z,

  • of a keyword you literally hardcode in array.

  • It's going to be some array in question.

  • And we'll see, wherein we have actual arrays.

  • That allows you to iterate over the values in an array.

  • JavaScript also has something called an object, though.

  • And Python has these, too.

  • And we've mentioned them a couple times.

  • Like technically, when you declare the db variable

  • for using CS50's SQL library, that is an object.

  • It's a variable that is an object type.

  • So we've seen these.

  • But we're going to see them ever more explicitly in JavaScript,

  • exactly what an object is useful for.

  • Meanwhile, we're going to have some, thankfully, familiar syntax.

  • And you're going to kind of revert back to your C days.

  • Because elif is not a thing in JavaScript. else-if explicitly is.

  • So there's that little nuance.

  • There's a declaration of arrays which look quite like Python lists.

  • So if you want-- and actually, let me fix this to be consistent.

  • Var is technically a keyword, too.

  • But it works a little differently than let.

  • So let's just define this as let numbers equals

  • square brackets these numbers here.

  • Notice the square brackets means it's an array.

  • But in JavaScript arrays can be resized.

  • They can grow and they can shrink, quite like what in Python?

  • AUDIENCE: List.

  • DAVID J. MALAN: List.

  • And quite unlike arrays in C. So again, there's just kind of these trade-offs.

  • And again, it's fine to Google these kinds of things like,

  • can you resize arrays in JavaScript, if you forget these kinds of things.

  • But these are the kinds of differences, when

  • learning new languages, that will eventually sink in.

  • So here is an example of what we'll call an object a.k.a.

  • a dictionary or dict in Python.

  • A dictionary, or more generally, a hash table has keys and values.

  • And that's it.

  • You can have fancier structure.

  • But at the end of the day, it's just a bunch of keys and values.

  • Different languages use different syntax for these, curly braces or colons

  • or equal signs or arrows or other funky things.

  • But the idea is the same.

  • And in JavaScript, if I want to declare a quote,

  • like a stock quote to be a data structure, like a struct in C,

  • with three keys--

  • name, price, and symbol.

  • I literally enumerate them here with colons after the names.

  • And then I put the values in quotes, if they're strings, or no quotes,

  • if they're not strings, on the right hand side.

  • So in the context of CS50 finance, a web-based application

  • for downloading stock quotes and more, if you

  • wanted to get a piece of data that represents Netflix's current stock

  • price, you might get back from the server something

  • that looks a little bit like this.

  • But technically, and not to throw too much at us at once, technically,

  • it's probably something in what's called JSON format, JavaScript Object

  • Notation, JSON format, which just has some additional quotes around things,

  • as here.

  • But we'll see that actually in use before long.

  • And besides that, besides that, that's kind of the essence, syntactically,

  • of JavaScript.

  • We're going to now see it's more powerful features and its programming

  • paradigms.

  • But if you know C and if you know Python, you kind of sort of already

  • know at least the basic syntax of JavaScript.

  • You just now need to know how and when and where to use it.

  • But syntactically, before we forge ahead, any questions?

  • No?

  • OK.

  • So let me go ahead and do this.

  • Let me go into the IDE and go ahead and whip up a little example, here,

  • that I'm going to go ahead and call dom0.html.

  • And we saw this term briefly some time ago.

  • But DOM refers to document object model, which

  • is a fancy way of saying the tree that represents a web page.

  • A web page, of course, might look, super simply, like this in HTML.

  • The hierarchy is there because of the open tags and close tags.

  • The indentation there is just because of me, the human,

  • wanting to be able to read it a little more prettily.

  • But this structure here in HTML could be implemented in memory

  • in any language using this kind of tree structure.

  • This tree structure is called the document object model.

  • And it's the right mental model, the way to think about what

  • a web page is underneath the hood.

  • So why is this useful?

  • Well, it turns out all this time when we've been writing web pages,

  • for the most part, we've written HTML or we've

  • written in Python that generates HTML.

  • Or that's what you're in the midst of doing now.

  • But what if you want to change a web page after the HTML has

  • been written or sent to the user?

  • You run it writing Python code, don't have the ability

  • to run Python code on your users' or your customers' computers.

  • Because it's only used on the server.

  • It sends out HTML and CSS and that's it.

  • You lose control over the user's experience.

  • Unless, in addition to the HTML and the CSS that you're sending the user,

  • you also send them some JavaScript, an additional program

  • written in this new language that runs, ultimately,

  • on their Mac or PC after it's left your server.

  • So let's see what this might mean.

  • Let me go ahead and whip up a little example like this.

  • So dom0.html.

  • We're going to have our usual DOCTYPE at the top that says, hey, here

  • comes HTML 5.

  • Here's the beginning of my web page.

  • It's good to have a head up here with a simple title like dom0.

  • The body of this web page is going to be pretty simple.

  • I'm going to go ahead and define a form that has a unique ID called demo, just

  • for demonstration purposes.

  • Inside of this form is going to be an input whose

  • ID is name, so I can access that too, whose placeholder, which is just

  • the fancy gray text, is going to be name,

  • and then whose type is going to be text.

  • And then I'm going to give myself an input type equals submit button.

  • So here I have, once I've saved that, a pretty simple web page that

  • simply has a very simple HTML form.

  • Let me go ahead and run this.

  • I'm going to go ahead and do this by simply serving.

  • By right clicking or control clicking on my workspace and clicking serve,

  • I'm going to see a very simple, ugly web server whose sole purpose in life

  • is to serve the HTML files I've written.

  • And I'm going to go ahead and click on dom0.html.

  • So this is the file that I just whipped up super simply.

  • If I type something in and hit submit, what's

  • going to happen with the information?

  • Nothing really.

  • I haven't wired it to anything.

  • I didn't have an action or a method attribute on the form.

  • I haven't finished writing this program.

  • So what do I want to do here to make this happen?

  • I'm going to go ahead and do this.

  • First, I'm going to go into the head of my web page

  • and instead of just having a title, I'm going to introduce a new script tag.

  • And as the name implies, here comes a script.

  • A script is generally synonymous with like short program.

  • The programs in a web page can be written, these days,

  • pretty much only in JavaScript.

  • Back in the day, you could use other languages,

  • especially in Microsoft browsers.

  • But for the most part, the world only uses JavaScript in this context now.

  • So inside of the script, I can start writing code.

  • In particular, I can do something like this, alert("hello,world");

  • It turns out, alert is a pretty lame, but a functional function in JavaScript

  • that's just going to print out an annoying pop up.

  • So let me go ahead and save the page, go back

  • to my browser, reload, and there we go, my very first interactive kind

  • of sort of web page.

  • That, really ugly, does this.

  • It just says, hello, world.

  • And I say ugly because it's showing my domain name and my port.

  • And that's just kind of lame and messy.

  • But at least I'm conveying some information to the user.

  • So it would seem that what a browser is indeed

  • doing when it receives an HTTP request is it's sending this file.

  • And then when your browser receives that file, it reads it top to bottom,

  • left to right, and executes or interprets every line of code.

  • So it doesn't just make things bold faced and centered and the like.

  • It actually will execute lines of code inside of script tags.

  • So let's make this, now, a little more interactive.

  • Instead of just calling alert like that, let's actually put it in a function.

  • And call it function greet.

  • Here are my curly braces back in our C days.

  • And here let me go ahead and just say, hello, world, now.

  • If I go and reload this page, am I going to see or not see the alert?

  • AUDIENCE: Not see.

  • DAVID J. MALAN: Probably not see, unless, for whatever reason,

  • the browser runs the greet function automatically.

  • And it doesn't.

  • It doesn't.

  • There's no equivalent of main in JavaScript.

  • And it certainly doesn't mean greet.

  • So nothing happens.

  • But it is there.

  • So suppose I want to now connect these things somehow.

  • What could I actually do?

  • Well in my form, you know what, instead of submitting to some end point--

  • like the action shall be to go to register or something like that--

  • let me actually say this.

  • On submit go ahead and call a function called greet;

  • So it's a little messy.

  • And we're going to clean this up.

  • But I've introduced a new HTML attribute that literally does what it says.

  • On submission of this form, call this code, execute this code.

  • And that code, defined up above, is going to greet the user.

  • So let's see.

  • Let me go to this web page.

  • And as always, reload the page so that you see the latest.

  • Let me go ahead and type in my name and submit.

  • And there we go, hello, world.

  • And then suddenly the page resets.

  • It actually reloaded itself.

  • So let me actually clean this up a little bit.

  • After calling greet, I'm actually going to return false.

  • Because technically, I don't have anywhere for the users name to go.

  • There is no server.

  • So I want to make sure that I've disabled the built-in functionality

  • of this browser.

  • So that now, when I type in my name and click submit,

  • it still works like before.

  • But notice, the web page stays the same.

  • It didn't reload.

  • It didn't take me elsewhere.

  • It just stayed put.

  • So now, I'm using the HTML form as a local application

  • and not really connecting it to anything on the server.

  • But this is a little annoying.

  • And you might have wondered why this does this.

  • Most browsers do this.

  • This eventually will get a little messy.

  • It's kind of compromising a bit of your privacy in forms.

  • How can I disable this functionality so that users' names are not

  • remembered in text boxes?

  • Well, if you've never known, we can simply do autocomplete="off".

  • And you might have seen this already in Pset 7,

  • or elsewhere on the web, that's how we do that.

  • And also let me go here and reload the page.

  • Notice that, how do I interact with this form?

  • I can't type my name by default when I visit the page.

  • Why?

  • And that probably wasn't good for my keyboard.

  • What would you do in this case to solve this stupid problem?

  • Yeah, like click over here.

  • And this is now an example, albeit a tiny one,

  • of a good versus a bad user experience or UX.

  • If the sole purpose of your web page is for the user

  • to type in his or her name, then why are you doubling the number of steps

  • so that the user has to click up here first in order, then,

  • to type his or her name?

  • Why not just automatically focus on the text box?

  • And indeed, that is an operation in a browser, to give focus to a form field.

  • So in fact, if I go back to my code here and I also add

  • autofocus and just as an attribute.

  • It doesn't strictly need a value in quotes or with an equal sign.

  • Now, if I reload the page with command r or control r, notice, now,

  • the cursor is blinking.

  • The text box is blue on Mac OS.

  • And it's ready to take my name right away.

  • So start to think about two of these little subtleties,

  • not just technically how they work or how to do them,

  • but also why you would do this.

  • Like my rant the other day about why a website can't accept

  • phone numbers in different formats.

  • These are the little things that start to distinguish good code from bad code.

  • And focus has another detail too.

  • So if I hit tab, it's very common, especially in Mac OS,

  • it's super obvious, where things become highlighted in blue.

  • So you can tab around a user interface.

  • Especially important for accessibility.

  • So if someone is using a screen reader because he or she can't actually

  • see the words on the screen, let alone the interface,

  • using tab and a screen reader can they actually be told what is on the screen.

  • And that highlighting, that so-called focus,

  • has very real functional value, so that they

  • know exactly what will happen if they start interacting with the website.

  • Will the button get clicked?

  • Will text end up in the box?

  • It depends on what has focus.

  • And only one thing can have focus at a time, per those blue boxes.

  • All right, so with that said, this is not all that elegant right now.

  • I'm kind of not practicing what we've long

  • been preaching about combining one language inside of another.

  • We started to go down this road some time ago.

  • I started putting CSS in my style attributes.

  • And then I put it up here.

  • And then finally, I got it out of there and put it into a separate file.

  • So we're going to be on that same trajectory here, too.

  • But let me go ahead now and do things a little differently as follows.

  • It turns out that just putting code inside of script tags like this

  • isn't necessarily the best practice.

  • We can instead-- because it requires doing this.

  • This is the ugliest portion of code.

  • And it might not be obvious now.

  • But bad practice, do not put code inside of double quotes in HTML.

  • Because you have one language again inside of the other.

  • It's not obvious what this page is going to do

  • when you glance at it at first glance.

  • If you're collaborating with someone, maybe you're

  • the front end user interface designer.

  • You're really good with design and art.

  • And so you're doing the interface.

  • And someone else is actually writing the code and the logic.

  • Because they like to do more of the back functionality.

  • You can't both really work as effectively if all of your work

  • is commingled in the same file.

  • So we want to get this out of there.

  • So how do we take a step toward that?

  • Well let me go ahead and create a new file.

  • I'll call this dom1.html.

  • And I'll start in the same place.

  • But I'm going to go ahead and do this.

  • I'm going to get rid of this event handler

  • and stop using that attribute altogether.

  • And I'm also going to go ahead and do this.

  • I'm going to get rid of my greet code.

  • I'm going to go ahead and get rid of the script tag, here.

  • And just for now, temporarily, I I'm going

  • to actually put the script at the bottom of the page for reasons we'll soon see.

  • So in the bottom of the page, now, I could do alert, hello, world.

  • But that, of course, recreates the same problem as before.

  • I don't want it to just happen always.

  • I want it to happen only when the form is submitted.

  • So how can I do that if I am trying to avoid this messiness, this commingling

  • of code and HTML?

  • Well, it turns out that there is a way to tell the browser

  • to do something when something happens.

  • Specifically, I can do this, document.

  • And document is now going to be a special global variable that

  • refers to my web page, the document that I'm writing.

  • document.getElementById, which is a long function name.

  • It exists in JavaScript.

  • And notice the capitalization of the E and the B and the I,

  • but not the initial g.

  • This is conventional.

  • In a lot of languages, you don't capitalize

  • the first letter of your function but you

  • do capitalize every word thereafter.

  • Something called camel case, where it's kind of going up and down

  • and up and down.

  • Because it's a little more readable than all lowercase

  • and certainly all upper case.

  • So what ID do I want to get?

  • I'm going to go ahead and get the ID, demo.

  • And we'll see what that means in a moment.

  • And I'm going to register an event handler as follows.

  • So let's finish this thought in a moment.

  • Where does demo come from?

  • Where did we see that before?

  • Yeah, a few lines earlier.

  • I just gave my form an arbitrary, but very unique, ID of demo.

  • I could have called it anything.

  • And I could have done this actually in different ways, too.

  • But this is just super explicit.

  • So here, even if you've never seen JavaScript before,

  • you can start to infer this is saying, hey document, hey web page,

  • get me the element ById("demo").

  • So somehow or other, this is a function that's

  • going to go grab from the browser's memory the square or the rectangle

  • that I drew earlier.

  • The reason that the DOM or document object model is interesting,

  • theoretically, is that with document.getElementById, you

  • have the ability to go grab one of these nodes in the tree

  • or one of these data structures in memory and do something with it.

  • Now, what are we going to do?

  • Well, we're about to see.

  • When I have access, now, to this form, it

  • turns out that forms, per the manual for HTML so to speak,

  • there are different event handlers on submit,

  • maybe on click, maybe on mouse move, mouse drag.

  • It depends on the element.

  • But forms can be, of course, submitted.

  • So literally, by saying .onsubmit, I can now say the equivalent of call this

  • function.

  • This is just pseudocode.

  • I now need to give this a function.

  • And so I can do this in a couple of ways.

  • I can do it like this.

  • So function greet is a function that simply does say, hello, world.

  • And now, at this point in the story, I've defined a function up here

  • and given it a name.

  • And then here I'm saying, on submission of the demo form, call this function.

  • But notice the difference.

  • It's subtle.

  • I didn't do this, which is the norm.

  • I instead did this.

  • Why, though subtle, is it probably important

  • that you omit the parentheses?

  • How to think about this?

  • AUDIENCE: Because it doesn't accept any arguments.

  • DAVID J. MALAN: It doesn't accept any arguments.

  • That's true, but it's not the reason for doing this.

  • Good thought, though.

  • Yeah.

  • AUDIENCE: So maybe nobody can change it.

  • DAVID J. MALAN: So no one can change it, not there, too.

  • I think anyone who has access to the file can certainly change my code.

  • So it's not that.

  • AUDIENCE: Because you're trying to send it to the output?

  • DAVID J. MALAN: Closer.

  • I'm trying to send it to the output.

  • Not quite, but I think we're on the right track.

  • AUDIENCE: So it doesn't call it right away.

  • DAVID J. MALAN: Yes.

  • So that it doesn't call it right away.

  • Ever since week one of CS50, any time we have seen a function name

  • followed by open paren, closed paren, maybe with some arguments inside,

  • that has meant call this function and maybe pass in these inputs.

  • But that's not what we want at this line of code.

  • At this line of code, we want the browser to know which function to call,

  • not to call it right then and there.

  • So we don't want that function to be called

  • as soon as we get to this line of code.

  • Because otherwise, we're going to see the alert, no matter what,

  • the moment the browser reads that line of code on the screen.

  • Instead, we just want to tell the browser, hey,

  • just so you know in the future, when the form is submitted,

  • here is the name of the function only to call.

  • But don't call it now.

  • And so that stupid, simple difference actually makes all the difference

  • in this case, functionally.

  • And so now let me get rid of this.

  • And leave the program as follows.

  • So now let me go ahead and go back to the web page, reload, click submit.

  • And we see, hello, world.

  • So the functionality hasn't really changed.

  • But at least I've made some progress.

  • But I haven't done quite as much as would be ideal.

  • It would be a lot nicer, I think, to do two things.

  • One, this is kind of lame.

  • I have defined a function called greet.

  • And then I'm using that function's name in one place only.

  • That suggests I never really needed this word greet in the first place.

  • You know, it's fine.

  • It's clear.

  • It's correct.

  • But you know what, I remember from earlier

  • that JavaScript supports anonymous functions that don't have names.

  • So how could I do this?

  • Well, it turns out we can just, in one fell swoop, do this.

  • Let me go ahead and cut and paste that and get rid of the excess white space

  • now, get rid of the function name, and now just do this.

  • And just for clarity, let me put the curly brace on the same line,

  • even though it doesn't strictly matter.

  • But this would be stylistically more common.

  • What am I doing now?

  • This is now saying, hey JavaScript, get the element

  • called demo or with an ID of demo and when it is submitted,

  • call this function.

  • Now, it's a subtle difference, again.

  • Open paren, close paren, here, does not mean call the function.

  • Because it's immediately followed by the curly braces, which means here

  • comes the code that should be executed when this function is called.

  • It ends with a semi-colon not because functions themselves

  • need to end with semi-colons, but this is all one long line of code

  • that I've just indented now.

  • Because we're declaring a function and assigning it from right to

  • left all at once.

  • So a huge mouthful there.

  • But again, none of the ideas are new except for the fact

  • here that functions can be anonymous with no name.

  • And you can pass functions around and call them later.

  • Any questions on this?

  • Yeah.

  • AUDIENCE: So can you remove functions and instead

  • just put equals alert, hello, world?

  • DAVID J. MALAN: Good question.

  • Can I get rid of the function and just do this?

  • Short answer, no.

  • Because if I do this, this is going to, just like in C,

  • call this function, which is going to display that alert.

  • And then it's going to assign the return value of that function, which I don't

  • think it has one at all, to onsubmit.

  • So this calls the function, assigns its return value,

  • which is technically undefined, to this.

  • So nothing will ever happen if you click submit thereafter.

  • It's going to get called prematurely.

  • So the way to avoid this is, again, to define a function

  • and then pass it in by its name only.

  • Or declare it anonymously, so to speak, like this.

  • So that you're really just telling the browser, on submit,

  • call this chunk of code in between the curly braces.

  • And that's it.

  • OK.

  • So this is still a stupid demo.

  • Because it keeps saying, hello, world.

  • And yet, I have a form with which the user can type in their name.

  • So how do I get at that value?

  • Well it's actually pretty straightforward here, potentially.

  • Let me go ahead and do this.

  • Hello, I want it to say, David, if I'm the one who types in my name.

  • But of course, I don't want to hard-code that.

  • I want to somehow get the user's name and plug it in here.

  • So how can I do that?

  • I can say let name equals document dot--

  • and just so we see where this is going, getElementById maybe name.

  • Because I have another ID.

  • Recall, I had the anticipation to write that line of code earlier.

  • So get the user's name.

  • And then it turns out you'd only know this by seeing it before, online,

  • or in class, .value will get me the text that the user has typed in, and then

  • semi-colon.

  • And now here, just like in C and in Python,

  • I'm not going to want to do this.

  • Because that's literally going to say, hello, name.

  • I want to plug it in.

  • And I can do this in a couple of ways.

  • Perhaps the most blatant is like this.

  • And those of you who did take APCS or the like

  • might know what plus means in Java.

  • This is just a coincidence that it also works here.

  • What does plus sometimes mean in languages besides addition?

  • AUDIENCE: Concatenation.

  • DAVID J. MALAN: Concatenation.

  • So in C, this would have been a pain in the neck.

  • Like, in C, this is where you got to whip out

  • like malloc or some really big array on the stack

  • and actually like plug one name into the other.

  • In Python, you can just concatenate things using pluses as well.

  • Or you can use f-strings or format strings.

  • In JavaScript, we can just do pluses like this.

  • And this will concatenate "hello," to the word name and print that out.

  • So let's actually see what happens.

  • If I didn't make any mistakes, when I reload this page and type in my name

  • and click submit, hmm, what did I do wrong?

  • What's that?

  • I forgot to refresh it.

  • I also forgot to change the URL, which I just now realized.

  • So now we're in demo1.html.

  • So let's reload now, David, submit.

  • And there we have David.

  • And just for good measure, let's go ahead and type in Maria, submit.

  • And it does seem to be changing dynamically.

  • So that's a nice improvement in that it's now doing that.

  • Do we strictly need this variable?

  • No, but if we have this variable, notice we can do this, too.

  • Just so you've seen this, in JavaScript, for better for worse,

  • now we have things called backticks, which is the key on a US keyboard

  • that's usually on the top left just below escape.

  • And if I have back ticks here, guess what?

  • You can do this, which is uglier than Python's f-strings,

  • but does the exact same thing.

  • And again, this is the kind of stuff where

  • you can start to roll your eyes as aspiring programmers.

  • Where if one language does something slightly different and you just

  • have to constantly remember, it's the same idea.

  • It's the exact same idea.

  • It's just different syntax.

  • So this would plug-in the name into those backticks.

  • And this is called a template literal in JavaScript.

  • All right.

  • Any questions on that thus far?

  • All right, let me introduce one final teaser, here, as follows.

  • Let me go ahead and go into our distribution code for today

  • and open up, let's say, in source 11, this directory here.

  • And in a moment we'll see all of the files in here

  • and show a couple of examples here.

  • So one, it's very common, of course, to have web-based forms

  • where the user may or may not actually give you

  • what you want him or her to type in.

  • And so it's nice to validate their input,

  • like we've been doing on the server.

  • But if you validate the user's input and make sure

  • that they've given you an email and a password and a password that's the same

  • and checked your terms and conditions check box and so forth,

  • you can do all of that in Python.

  • And we've seen how to do that in application.pi.

  • But it's a better user experience, UX, if you actually

  • give the user more immediate feedback, maybe prettier feedback,

  • by using some colors and highlighting on the screen

  • to draw their attention to what's actually wrong.

  • With JavaScript, we have that capability.

  • Moreover, in JavaScript, we have the capability to do something like this.

  • So if I now run the web server in today's distribution code

  • and open up this URL, I'm going to see a listing again.

  • But I'm going to go ahead now and pull up say ajax1.html.

  • And here, I have a very simple web form, not unlike,

  • in spirit, what you have in CS50 finance.

  • But if I want to see what the stock price is of Netflix,

  • I can type that get quote and I can actually get it in the client alone.

  • I don't need to send them to another route.

  • I don't need to use Python, it seems, to actually render a template.

  • I can just interact with the form directly and do this.

  • And then lastly, just a tease, we can do something like this whereby,

  • if I actually con--

  • damn it-- if I actually configure things correctly,

  • we can actually get ourselves a full fledged map using JavaScript.

  • So that in the end, we can use JavaScript and start

  • to make interactive applications, like this one here,

  • using Google Maps' API so that the user can click and drag

  • and can actually interact with it.

  • As by clicking on say, Stanford, California,

  • and seeing what's going on in the news in Stanford, California right now by,

  • again, writing code that executes in the browser, talks to some other server,

  • gets the data back, and renders it.

  • So we've just begun by introducing JavaScript to see

  • the syntax with which we can do this.

  • Let's take our 5 minute break here and then

  • actually start building some of these things to see how they interact.

  • All right.

  • All right, we're back.

  • And recall that the form that we created a moment ago just looks like this.

  • It's pretty simple, ugly HTML.

  • There's no CSS.

  • We're focusing only on functionality here.

  • I did, at least, give autofocus to the email field,

  • so I could start logging in right away.

  • But I want to achieve this behavior.

  • You know what, I don't really want to cooperate.

  • I just want to register and see what happens.

  • I want to validate this form.

  • So here's one way.

  • I seem to be using the alert method and saying missing email.

  • I'm not letting the user actually register.

  • OK, so let me slightly cooperate, malan@harvard.edu, register.

  • Missing password, it now says.

  • All right, so let me go ahead and give it a password.

  • One, two, three, four, five, register.

  • Passwords don't match.

  • Of course they don't.

  • Because I didn't type it in.

  • One, two, three, four, five, register.

  • Passwords still don't match because I accidentally typed six.

  • Register, check box unchecked, and so forth.

  • And only once I check that box and now click register do

  • I actually want the form to go through to the server.

  • So how do we start to impose that kind of logic?

  • We could do what you're doing or have done in CS50 Finance, whereby

  • you check on the server and make sure that the user has given you

  • email, password, confirmation, and a check box.

  • And if not, you show them grumpy cat and you

  • complain that they haven't cooperated.

  • And that's all cute the first time around,

  • but it's not the best user experience.

  • Because now the user has to click the back button

  • and they have to refill out the form and then do it again.

  • It would be nice to just get more immediate feedback

  • like we're getting here.

  • And not necessarily as ugly as this feedback,

  • because this alert is really just for debugging purposes, I would argue.

  • But at least it's quick.

  • And it's not even bothering talking to the server.

  • So here is the HTML with which we might create that form.

  • For the most part, this is cookie cutter,

  • whereby I'm disabling autocomplete on, I was overzealous with my autocomplete.

  • It's not strictly necessary for passwords.

  • Because browsers won't do that by default.

  • So really, I just want it to look like this, which is even smaller.

  • So I have a field called email of type text.

  • I have another field called password of type password.

  • I have another field called confirmation also of type password.

  • And then I have an input of type check box called agreement

  • followed by the submit button.

  • So that's it.

  • So how do I begin implementing some of the logic we just saw?

  • Well, let me do this.

  • Down here in the script tag, eventually we're

  • going to factor this out to another file,

  • but for here, I'm going to do this.

  • I'm going to go ahead and declare a variable called form and go ahead

  • and get via document.getElementById("registration").

  • Why that?

  • Well, notice that I gave a unique ID to my registration form

  • just because I want to be able to easily get at it, as here.

  • Then, I know that forms have submission handlers, so I can go ahead and say,

  • hey browser, on submission of this form, go ahead and call

  • the following function, albeit an anonymous function.

  • So all that remains for me to do is to implement this anonymous function.

  • What do I want to do when the user clicks the submit button?

  • I want to validate their input in some way.

  • So let me go ahead and do it sort of logically.

  • If this form's email field has a value from the user that

  • just equals quote/unquote, then let me go ahead

  • and alert the user that you are missing email, semi-colon,

  • and I'm going to return false.

  • Because that's it.

  • I'm not going to return true.

  • Return true would mean, let the user submit the form.

  • Return false means, stop submitting the form.

  • Let the user try again.

  • And so let's do this now for passwords.

  • So how about else if the form's password field has a value that also equals

  • quote unquote, then go ahead and alert the user

  • missing an s, missing password, semi-colon, and also return false.

  • Next one is a little more interesting.

  • Because now I can say else if form.password.value.

  • What do I want to say logically here?

  • AUDIENCE: Dot length.

  • DAVID J. MALAN: Dot length, I could do that.

  • So that's not a track I currently have in the UI we saw.

  • AUDIENCE: Can you find some sort of confirmation?

  • DAVID J. MALAN: The confirmation, yes.

  • So it turns out the syntax is the same as in C,

  • not equals form.confirmation.value.

  • Then, I want to go ahead and say, I think I said,

  • password, what did I say, passwords don't match, semi-colon,

  • return false as well.

  • And then the check box is a little different.

  • I can say else if it is not the case that the form agreement box is checked.

  • And that's a Boolean that's associated with a check box.

  • And you would only know this from the documentation for JavaScript.

  • But the not inverts it.

  • So if it's not checked, then go ahead and alert the user

  • that the check box is unchecked and return false.

  • But if none of those conditions apply and we make it

  • through this gauntlet of error checks, what

  • do I probably want to do down here?

  • What do I want to return?

  • AUDIENCE: Return true.

  • DAVID J. MALAN: Yeah, return true.

  • And that just means, hey browser, do what you want to do by default.

  • I'm done error checking the user.

  • So there's some opportunities for refinement here.

  • I could say, I don't really need to compare against the empty string.

  • I could say, if there's not a value, which is a little tighter.

  • And I can say, if there's not a password,

  • so I could clean it up that way.

  • I could actually use the string length, which is a thing, too.

  • So I could say something, if I really wanted to be nit picky,

  • else if the form's password value.length is less than 8 characters,

  • I can say something like alert, password too short,

  • which would be a nice check, as well, and return false.

  • If I really want to be secure, I can make sure the user has a pretty random

  • looking password, maybe with some numbers or some special characters

  • or some of those somewhat annoying, but probably good, constraints,

  • at least if you're using a password manager.

  • And this is how websites do exactly that.

  • But there's still an opportunity for improvement here in a couple of ways.

  • This code is, again, commingled with my HTML.

  • But this is actually an easy fix.

  • Let me go ahead and copy all of this code or highlight all of this code

  • that we just wrote, cut it out, and indeed I'm

  • going to get rid of the script tag altogether.

  • And instead in the head as my web page, where previously we've

  • only ever put titles and maybe some style or length tags for CSS,

  • I'm going to go ahead and say script tag the source of which

  • will be form1.js for JavaScript.

  • And even though this looks a little weird,

  • this is indeed the right way to do it.

  • It's an open tag and a close tag.

  • It is not valid, for silly reasons, to do this.

  • So even though this kind of makes no sense, do this nonetheless.

  • That's the way the world is.

  • So let me create another file, paste that very code I just wrote.

  • Let me go ahead and unindent it just to keep things cleaner.

  • Actually, it's not quite indented properly.

  • Now let's do this once more.

  • Let me save this as, what did I say, form1.js, save.

  • And now I have a better version of this.

  • And what is the browser going to do?

  • Well, just like when we've used images in our web pages before,

  • like the cat, by referencing an image source equals quote unquote,

  • so do we have a script source equals quote unquote something here.

  • So now when a user visits this page, form1.html,

  • the browser is going to read it top to bottom, left to right.

  • It's not going to see any actual JavaScript.

  • So nothing's going to execute right away.

  • But it is going to see this other file.

  • And it's going to recursively, if you will,

  • download that file so that the web page has access to all of the code therein.

  • So that would be one refinement.

  • And now we're back to what, I would argue, is a better design.

  • But there is another way to do this.

  • And let me open up a premade version of this.

  • It turns out that some things in JavaScript can be pretty tedious.

  • Because the language, early on, was pretty immature.

  • And people were trying to get it to do things that just weren't

  • very easy to do in the language.

  • And so popular libraries arose, as was the case in Python as well.

  • And here we have an example called form2.html

  • that actually uses a library that, for some time,

  • was one of the largest and most popular called jQuery.

  • JQuery is not a language unto itself.

  • It's literally just code that a bunch of nice people

  • wrote to make it easier to use JavaScript for certain things.

  • The price we pay for that ease of use is that some things are actually

  • a little more syntactically weird looking.

  • And so we won't dwell too much on the syntax of jQuery.

  • But jQuery is the library for JavaScript that Bootstrap uses.

  • And you might recall Bootstrap from the past couple of weeks.

  • Anytime we've made prettier websites than I'm typically capable of, when

  • they have nice forms and everything is nicely color coded

  • and they resize nicely, that's because we're

  • using the Bootstrap CSS library that also

  • comes with some JavaScript interactive features that

  • require that you have jQuery linked in your web page, as well.

  • So that's why we'll use it here, as well as to see the following.

  • Here, now, is another implementation of the same program in between script

  • tags, for now, inside of my head.

  • But I've done a couple of different things.

  • This line of code is perhaps the weirdest looking at first glance,

  • in part, because of this dollar sign.

  • And we saw a dollar sign a moment ago inside of those strings

  • with the backticks.

  • This one means something different.

  • As soon as I import this file, which is the latest version of jQuery,

  • so it's hosted elsewhere, not on my own IDE,

  • it turns out that gives you access to a global variable called jQuery,

  • spelled like that.

  • Back in the day though, the people who wrote jQuery

  • decided that that's a little tedious if every time the users in the world

  • want to use our library, they have to type out this kind of long word jQuery.

  • So it turns out they just created an alias for it called dollar sign.

  • And weirdly, in JavaScript dollar sign and a few other punctuation

  • symbols are actually legitimate characters to use in variable names.

  • This is not true in C. This is not true in Python.

  • But it is true in JavaScript, that even though this looks funky to all of us,

  • at least relative to the letters of the alphabet, it's a valid symbol.

  • It could have been fu or bar or x or y.

  • So jQuery just kind of got there first and claimed for the world,

  • we shall use dollar sign for all of our functionality.

  • That's all it means.

  • So what does this functionality do for us?

  • This is a mouthful.

  • But let's see if we can parse what's going on.

  • Document is what, in your own words, anyone's words?

  • Yeah.

  • AUDIENCE: The web page.

  • DAVID J. MALAN: The web page.

  • It is a global variable referring to the very web page we're looking at.

  • That's the so-called document.

  • This syntax here, dollar sign open paren, close paren,

  • is the way in jQuery to wrap, literally, the document

  • with some additional functionality.

  • So the browser gives you this global variable document.

  • And it's got some functionality built in, like getElementById.

  • And there's other stuff too.

  • But we won't look in detail at it.

  • This dollar sign open paren close paren around it, takes that global variable

  • and stuffs even more functionality into it

  • just to make it even easier for us humans to use.

  • One of the pieces of functionality it gives us is this function called ready.

  • And ready, a little unusually, but similar to what we just saw,

  • takes an argument as its input.

  • And that argument is a function.

  • The function that should be called when the document is ready.

  • That's it.

  • Because web pages can be pretty big, right?

  • You go to cnn.com or Google News or Facebook or Gmail,

  • it kind of takes some number of milliseconds or sometimes even seconds

  • for the whole page to load until you finally

  • see the entirety of the web page.

  • That means the web page is ready, once you see everything on it.

  • So the way you can say, programmatically, hey browser,

  • only execute the following code when the document is ready,

  • is with the line of code like this.

  • And it's fine if you have to copy-paste that for now until it sinks in.

  • But that's all it's saying.

  • Add some functionality to the document, like this ability

  • to wait until the web page is ready.

  • And then when it is ready, call this anonymous function i.e.

  • this chunk of code.

  • So what's happening below that?

  • Well, it turns out, there's just alternative syntax

  • in jQuery for doing the same thing we just did.

  • Though cryptic looking, this dollar sign with the parentheses

  • takes an argument here that's different from document.

  • If you pass in a string, that kind of looks like CSS,

  • recall that we've used CSS selectors before,

  • where you can either have a tagged name in your CSS file or hashtag

  • something, which is the ID, the unique ID, in a file.

  • Or dot, which meant a CSS class, vaguely.

  • So look back at some of your CSS examples if you don't quite recall.

  • But in CSS, those are selectors.

  • And this one just means, grab the dom node whose unique ID is registration.

  • jQuery syntax for that same expression is this.

  • So this line of code is essentially equivalent

  • to document.getElementById("registration")

  • And the reason that jQuery exists is that they say in about half

  • as many characters what it just took me twice as many characters to type out.

  • That's all.

  • It's not a new idea.

  • It's just more succinct, if more cryptic.

  • And moreover, if we keep going, in raw JavaScript, it's onsubmit.

  • In jQuery, it's .submit.

  • Just because, why do we need those two extra characters?

  • We don't really.

  • So that's all we're seeing here.

  • So what actually happens, now the syntax,

  • admittedly, gets a little funkier.

  • So we won't spend too much time here.

  • But if you did not have the foresight or for whatever reason did not

  • want to give unique identifiers to all of your form fields, that's OK.

  • Because you can use CSS-like selectors, fancier

  • ones than we've introduced in the class, that say hey,

  • go look in the web page for the element whose unique ID is registration.

  • Look inside of it, it's children or descendants,

  • for an element of type input.

  • And then, only grab the value of that input if its name is email.

  • So again, we won't dwell on this.

  • Because there are easier, simpler ways to do this.

  • But with jQuery, you get the expressiveness that we're seeing here.

  • And all the rest of the code on the screen

  • simply does the exact same thing using another syntax.

  • So use this more as a crutch when experimenting with, say,

  • for the next project or final project, jQuery,

  • if you want to see analogues from no jQuery to yes jQuery,

  • but it does nothing fundamentally different.

  • It's just a different syntax.

  • But there is going to be a more powerful feature that we now get from jQuery.

  • It turns out that when you do visit websites

  • like maps.google.com like this.

  • This is not the whole world.

  • At the moment, it figured out that I'm in Cambridge.

  • And it's showing me just a little snippet of Cambridge.

  • And Google also, even though I'm only looking at Cambridge,

  • also did not proactively download pictures of the rest of the world

  • and store them in my browser's memory.

  • That's be pretty stupid.

  • Because I rarely need to go very far away from where I am.

  • And even so, if I want to go to like New Haven,

  • I don't really need all of the cities and towns between me

  • and New Haven to be in my browser.

  • We can just jump straight there.

  • And you can kind of see this artifact, as follows.

  • If I click and drag really quickly, what do you see happening?

  • I should have gone somewhere where there is land.

  • What do you see happening on the left, as I do this quickly?

  • AUDIENCE: There is a delay.

  • DAVID J. MALAN: Yeah, there's a delay.

  • You see these gray tiles, like placeholders,

  • until eventually, they're filled in.

  • Now why is that happening?

  • Well, you know what, I'm going to go up to my browser's developer

  • menu, developer tools, which should be a habit you're increasingly getting

  • into when you want to understand something or solve some problem

  • or just learn out of curiosity.

  • Let me clear this temporarily.

  • But every time I click, whoa.

  • Just clicking and dragging induced, as of now, 89--

  • whoops, there there's my screen saver--

  • 92 more HTTP requests.

  • So what is it that's being requested, do you think, every time I click and drag?

  • More images, more tiles, as they're called in Google Maps.

  • And so what is the feature of browsers that

  • allows them to go get more and more data like this on demand?

  • This is a technology or technique called AJAX.

  • AJAX is just a fancy way of saying a feature in browsers

  • that lets them execute HTTP requests after the first one is all done.

  • Which is to say, when you first visit Facebook or Gmail or Google Maps

  • and you get back a response from the server containing the map of Cambridge,

  • the browser, thanks to AJAX, which is a more modern technology

  • over recent years, has the ability to send more of these envelopes

  • out onto the internet saying, I need the tiles for the northeast corner.

  • Or I need the tiles for the southwest corner.

  • Send them back to me.

  • So constantly, we're now up to 651 additional envelopes

  • came back from Google in order to fill in all of the blanks

  • as I sort of rapidly clicked and dragged to different locations.

  • And it doesn't have to be graphical in this nature.

  • We saw stock quote a moment ago.

  • And that's, perhaps, an even simpler paradigm,

  • if I just want to get some slightly additional information.

  • So let's do that, let me go ahead and open up ajax.html.

  • And I see this form here.

  • And now let me go ahead, as should be, again, increasing habit,

  • go to my network tab.

  • And notice, just for good measure, also get into the habit

  • of clicking preserve log.

  • So that just in case the web page redirects or goes elsewhere,

  • it doesn't delete everything you were looking at.

  • You still see everything.

  • Let me go ahead here and type NFLX for Netflix and get a quote.

  • And notice, we saw earlier, the response come back from the server.

  • As of this moment, it's $198.41, but how do we know that?

  • Let me dismiss the alert and focus down here.

  • After loading this page, apparently, it sent one more HTTP request,

  • which was successful.

  • Why?

  • Or how do I know?

  • Yeah, 200 OK.

  • So Chrome is showing me that, too.

  • And you can do this in Edge and in Firefox and Safari.

  • But frankly, Chrome is sort of the go to browser these days for development.

  • So I would encourage you to keep using it for this.

  • If I click on this, I can now see what the request was and the response was.

  • Here are all those headers.

  • There's some cookies involved, which are a result of the IDE

  • and not my own code.

  • But it's the response I care about.

  • Let me view the source.

  • And notice, a few things came back, some of which are familiar,

  • some of which aren't.

  • Among the headers is indeed 200 OK, so that's a good thing.

  • Notice what type of content came back, though.

  • In the past it's been text/html.

  • But what came back this time?

  • Yeah, application/json.

  • Application is a little weird.

  • It's not an application.

  • It's not a program.

  • But it's a format used by programs, you can think of it.

  • JSON is JavaScript Object Notation.

  • So probably, what came back is something with some curly braces and colons

  • and quotes.

  • We'll see in a moment, 47 bytes worth, in fact,

  • and then some other stuff came back from the server as well.

  • So let me click on response.

  • And what do you know, in the response from the server

  • is not another web page.

  • There's no HTML tag, body tag, head tag, or anything.

  • It's just this text, but in an official format.

  • Open curly brace, close curly brace means here comes a JavaScript object.

  • What is an object?

  • It's a hash table or a dictionary with keys and values.

  • What are they?

  • A key is name.

  • Value is Netflix.

  • Price is a key.

  • 198.41 is a value.

  • Symbol is a key.

  • Netflix is a value.

  • And so it's just a way of getting back one or more pieces

  • of useful information.

  • So how do I now do this and how do I get the information back?

  • For that, we have to look at the code itself.

  • So in ajax0.html, we have this code here.

  • In HTML form, that, just like our very first example today,

  • just simply hard-coded inside of an onsubmit attribute,

  • a quote function call, and then return false.

  • That is, don't reload the page, don't submit the form for real,

  • just call the quote function.

  • Where is the quote function defined?

  • At the moment, a little lazily, it's defined in the same file.

  • But that's fine.

  • Because this is our very first.

  • Notice that I have two things for JavaScript.

  • One, is jQuery, that library I mentioned earlier, it has to come first.

  • Because just like in C, you need to know that functions have

  • been loaded before you use them later.

  • Then here comes my own script, my own JavaScript.

  • And here's my quote function.

  • It doesn't take any arguments.

  • Because we're going to get those in code from the browser.

  • And the syntax here is a little funky.

  • But we'll distill it in just a moment.

  • Dollar sign is synonymous with what?

  • AUDIENCE: JQuery.

  • DAVID J. MALAN: JQuery.

  • So this is just a prettier or confusing way of saying this.

  • JQuery.getJSON.

  • GetJSON is a function, or a method, so to speak, whose purpose in life

  • is to do that, go get me some JSON data.

  • From where should I get it?

  • /quote, which we'll see in a moment, is a super short route that I implemented

  • in Python on the back end.

  • Though, it could have been implemented in any language.

  • This looks a little cryptic, so we'll come back to this in just a moment.

  • So let me delete this temporarily and just say the following.

  • The getJSON function that comes with jQuery

  • takes at least two arguments in this case.

  • One is the URL, to get JSON from.

  • And two is what, would you infer?

  • AUDIENCE: An anonymous function.

  • DAVID J. MALAN: A what?

  • AUDIENCE: An anonymous function.

  • DAVID J. MALAN: An anonymous function.

  • That anonymous function, though, unlike the ones we've seen before,

  • actually takes input this time.

  • So it doesn't have a name.

  • And that's no big deal.

  • But it does take one argument-- data.

  • And this is an example of using an anonymous function

  • as what's properly called a callback.

  • Because the internet can be slow.

  • And if I am trying to get a stock quote from /quote,

  • maybe it comes back super fast.

  • But maybe the server is overloaded.

  • Maybe my internet connection is slow.

  • Maybe I'm on my phone.

  • And so it might take a second or two seconds to get that response.

  • And imagine if things waited in the world of the web for data to come back,

  • your experience, your user experience, your UX could be pretty bad, right?

  • The whole browser might hang or wait or you get the stupid spinning beach ball

  • while you wait for something to happen.

  • Imagine that in Facebook, like every time your friend is

  • typing you see the dot, dot, dot.

  • But maybe you can't do anything with the website until he or she hits enter

  • and you finally get the message.

  • That would be blocking you from doing real useful-- well,

  • "real useful things" from using Facebook in other ways.

  • So how can you instead tell the browser, go

  • get me something more, more tiles of the map, more messages

  • from my friend, more stock quotes from a server,

  • but call me back when you have the data so that I can actually keep doing work?

  • Just like, I might be at my desk here.

  • And actually, Brian, if you wouldn't mind coming up.

  • And Brian may be here is in his little home office.

  • And I am really curious as to what Netflix's stock price is.

  • So let me go ahead and pull up Brian, here.

  • BRIAN: Hello.

  • DAVID J. MALAN: Hi, Brian?

  • BRIAN: Hi.

  • DAVID J. MALAN: Hi, this is David

  • BRIAN: Hi, how are you doing?

  • DAVID J. MALAN: Hi, I'm really good, thank you.

  • I need the current stock price of Netflix, please.

  • BRIAN: The current stock price of Netflix, I'll work on that.

  • But I'll have to call you back.

  • It'll me a little while.

  • DAVID J. MALAN: OK, thank you.

  • BRIAN: No problem.

  • finance.cs50.net.

  • DAVID J. MALAN: Oh, hello?

  • BRIAN: Hello?

  • Hi.

  • The current share of Netflix cost $198

  • DAVID J. MALAN: Wait a minute, I'm getting a call from Colton.

  • BRIAN: OK, and $0.35.

  • DAVID J. MALAN: Hold on I got to call you back Colton, once sec.

  • Wait, hello?

  • BRIAN: Hi.

  • DAVID J. MALAN: Oh, hi Brian.

  • BRIAN: A share of Netflix costs $198.35

  • DAVID J. MALAN: OK, thank you very much, Brian.

  • BRIAN: No problem.

  • DAVID J. MALAN: Goodbye.

  • OK, I just hung up on Colton on the internet.

  • So thank you.

  • OK, so what was the point of that unexpected surprise and how weird

  • that he called me right at that moment?

  • So the point is that callbacks are something

  • we're already familiar with, right, in the real world where you actually

  • want to get some information back from someone.

  • And maybe it's not as contrived as hey, I need a stock quote quickly,

  • get back to me.

  • But you do wait for them to get back to you with some information.

  • How do you implement this in code?

  • This is the exact same idea.

  • So we have this special function called getJSON.

  • It's baked into this library called jQuery, whose nickname is dollar sign.

  • I then say, go get me some data from /quote or, equivalently,

  • Brian in the real world.

  • And then, I tell getJSON, when you are ready with this information,

  • call me back, so to speak.

  • How do you call me back?

  • Well, you know what, I'm going to write in advance some code that I

  • want you to call, literally, but in a computer sense, when the data is ready.

  • So just as Brian verbally gave me that stock quote, passing it verbally

  • back over the phone, so can this anonymous function

  • receive as an argument a data parameter or argument

  • that I, then, can have access to.

  • So I can use dot notation, like in C, structures,

  • and get at the name or the price or the symbol, which were the three

  • values that we saw in that JSON object.

  • But meanwhile, this line of code executes instantly.

  • And it registers, if you will, a callback function with getJSON.

  • So it just knows whom to call back.

  • And what this means in real terms is that if my web page were far more

  • interesting than this and is Facebook or G-mail with lots

  • and lots of other features, I can get back

  • to working on and using those features and then get interrupted if and when

  • the phone actually rings or the message comes in from my friend

  • or I get a new email or I get, in this case, a stock quote back.

  • So all that happens super quickly on a fast internet connection, but not

  • necessarily the case on a slower one.

  • As we started seeing with Google Maps, trying to get more and more titles.

  • But how can I clean this up?

  • So that was version 0.

  • Let me go ahead and open up version 1 here.

  • And notice that this time, I'm doing things a little bit differently.

  • Oh, and actually, let me reveal one last thing by way of this example here.

  • So what are we actually doing differently here?

  • So in this case, I'm now attaching-- let me open up the other one so we can go

  • there and back--

  • in this first version, recall, I did the sloppy kind of thing

  • where I commingled my HTML and my JavaScript.

  • And that's bad design.

  • Don't do that, even though that's where we started the story.

  • So how can I do this, programmatically, in code?

  • Well, if this is my form now, and notice there's no mention of onsubmit.

  • There's no mention of that attribute.

  • I'm doing this entirely in code.

  • How can I do that?

  • Well, I can say, when the document is ready,

  • go ahead and register this submit handler, if you will.

  • Event handler would be the generic term for all of these kinds of things.

  • When that form is submitted, call getJSON of /quote.

  • Then call this number back, so to speak, when the data is ready.

  • And I deleted this, temporarily, earlier.

  • But let's tease apart what this is.

  • It's a little cryptic looking.

  • So let me clean that up as follows.

  • Let me go ahead and say the following, let my HTTP parameters

  • be this JavaScript object that has a symbol and whose

  • value is this thing here.

  • And this is a little cryptic, too.

  • But we'll tease this apart in just a second.

  • So let me now replace this with HTTP parameters.

  • So what's going on here?

  • I'm just being more verbose, but it's no more correct.

  • Here is a variable called HTTP parameters.

  • What type of variable is it?

  • It's an object in JavaScript, note the nomenclature,

  • because of the curly braces.

  • That's the clue.

  • An object, recall, has keys and values separated by colons.

  • So here's a key symbol.

  • And here is a value.

  • This is a very funky way of writing it.

  • But this is jQuery's way of saying this--

  • document.getElementById("symbol").value.

  • So again, the value, no pun intended, of using jQuery in contexts like this

  • is just fewer keystrokes.

  • It's more cryptic.

  • You kind of have to remember the syntax over time.

  • But it's fewer things to type.

  • And that's all it's doing.

  • It's getting the symbol's value from whatever the user typed in,

  • like an NFLX for Netflix, and then it's storing it as the value of this key.

  • And then to getJSON, It's passing in those HTTP parameters

  • to create the URL I expected.

  • And what was the URL I expected, expected in the sense of me

  • being the programmer?

  • Well, if I hover over the URL in Chrome's log,

  • I visited /quote question mark, symbol equals NFLX.

  • So it seems that what getJSON is doing for me is actually constructing,

  • dynamically, a GET request.

  • Just baking into the URL the parameters that I want to pass in.

  • And so that example does, fundamentally, just that in the end.

  • So any questions, then, on AJAX or any of the syntax with which we're

  • doing this?

  • Yeah?

  • AUDIENCE: Why is the keyword symbol not between quotes?

  • DAVID J. MALAN: Good question.

  • Why is the word symbol not between quotes?

  • It could be.

  • This would be perfectly correct, too.

  • It's not strictly necessary when you're providing it as input, shall we say,

  • in this context.

  • It is necessary in the output.

  • So for stupid reasons, the JSON format that

  • is meant to come back as the response, everything must be quoted.

  • But when you're actually writing JavaScript code with objects and keys

  • and values, you don't strictly need to quote things.

  • Just bad design in the language.

  • Other questions?

  • All right, so if then, the take-aways thus far

  • are JavaScript has functions and anonymous functions,

  • which is kind of interesting, loops and conditions and variables and more,

  • even though we've not really used some of those features,

  • like loops and conditions.

  • Because we've kind of beaten them to death with Python and C.

  • They are in there.

  • But more importantly, there is this notion

  • of callbacks, the ability to call a line of code

  • and then say when you're ready with your return value,

  • call me back by calling this function.

  • This is an example of what's called asynchronous code in contrast

  • with synchronous.

  • Up until now, almost everything we've written and everything we wrote in C

  • was synchronous, which means if you run a line of code

  • and that function takes awhile to run, your code

  • is going to hang there for some amount of time.

  • And God forbid you've got an infinite loop,

  • it's going to hang there forever and block everything.

  • We started to see asynchronous code in Python,

  • even though we didn't call it this, just a week or two ago when

  • we started using Flask.

  • Because Flask is asynchronous in the sense that you write your program,

  • it registers all of those routes, and then it just kind of waits for things

  • to happen asynchronously, sort of out of order, in any order.

  • But now in JavaScript, we really feel the power

  • of asynchronous in the following way.

  • The reason that I was able to sort of--

  • actually, I didn't really do anything useful with my time.

  • I just kind of twiddled my fingers here.

  • But theoretically, I could have made another call.

  • I could have checked my email.

  • I could have gotten a snack while I wait for Brian to get back to me.

  • I could have gotten real work done.

  • Because if you allow for asynchronicity, you

  • can do stuff in between the starting and the finishing of some goal.

  • And that was just like when Brian called me back,

  • I could have used that time usefully, just like my program or my website

  • could do other things while I wait for this data.

  • So the value, then, of asynchronicity is that we

  • can be ready to do more things at once.

  • And what are some of the things we might want to do?

  • Well, let me open up some remaining examples, here, as follows.

  • Let me go ahead, here, and open up this one.

  • So this is built-in functionality that's actually kind of cool,

  • even though it's a little verbose.

  • If you've ever noticed, web pages these days

  • and certainly mobile applications can know where you are.

  • Frankly, Google knew where I was when I pulled up

  • Google Maps, even though I was not logged in, which is a little creepy.

  • But they had enough information about me.

  • How could you be as creepy in your own web sites

  • and figure out where the user is?

  • Maybe, I shouldn't have teed it up like that.

  • Well, this is a mouthful.

  • But the ideas are exactly the same.

  • Here, it turns out, there is another global variable

  • that comes with browsers these days.

  • It's not just document.

  • There's also navigator.

  • And navigator is like this special global variable

  • that's got geographic related functionality built into it.

  • One of those pieces of functionality literally is navigator.geolocation.

  • So this is like a feature inside of this global navigator object.

  • It comes with a function, otherwise known

  • as a method called current position.

  • Which, literally, if you read the documentation,

  • is supposed to get the user or technically

  • the browser's current position in the world, latitude, longitude, using

  • GPS coordinates or the like.

  • But that can take awhile to figure out where the user is.

  • If we were talking in a CSI sense, it's got to triangulate the user

  • and figure out where they are and do all of this,

  • sometimes talking to the server.

  • Somehow their position is determined.

  • And it could take a second, a minute maybe, some amount of time.

  • So that's a good opportunity for an asynchronous implementation,

  • to use a callback like we did with Brian.

  • So that when the browser does figure out my location,

  • let me know so that I don't see some annoying beach ball spinning

  • until that answer comes in.

  • So how do I do this?

  • I call getCurrentPosition.

  • I pass in an anonymous function, though it could have a name.

  • But it doesn't need it.

  • An anonymous function that takes, per the documentation,

  • one argument called position, which is going to be a special object containing

  • coordinates.

  • When that function is called some seconds or milliseconds later,

  • this one line of code here is going to execute, document.write,

  • which we haven't seen.

  • But this is just a way of writing additional words to the document,

  • like the web page, the body.

  • position.coords for coordinates, .latitude.

  • And then concatenate a comma just to keep it pretty.

  • And then concatenate position.coords longitude.

  • So this is a huge mouthful for saying, do the following.

  • Let me go into the web page called geolocation.html.

  • And nothing seems to happen yet.

  • But if I--

  • Why did nothing happen?

  • Oh, no.

  • OK.

  • There we go.

  • So it wasn't working because I wasn't accessing today's demos

  • by HTTPS, which isn't a big deal.

  • Because they're just public demos anyway.

  • But the browser didn't like it.

  • Because it wants the communication of my GPS coordinates to be secure.

  • So as soon as I change to HTTPS, it says,

  • hey, this domain name, my own on the IDE, wants to know your location.

  • Now, some of us might be in the habit of just clicking block.

  • Some of us might instead be in the habit of just clicking allow.

  • Some of us might be in the habit of clicking enter

  • and who knows what just happened.

  • But if I do click allow and wait, because it's asynchronous,

  • Brian could be taking awhile to figure out where I am.

  • There are my incredibly precise, using floating point values,

  • location in the world, at least with high probability.

  • Now, I can check for this, I believe.

  • This just happens to be Cambridge, Massachusetts.

  • If I go to Google Maps and search for those GPS coordinates,

  • indeed that is pretty darn scary.

  • So that's pretty good.

  • That is, in fact, where we are.

  • So the takeaway is, how can we do this?

  • Well, we can do this by understanding what a callback is

  • and what asynchronous code is.

  • But again, the paradigm is changing.

  • I'm not just calling getCurrentPosition and then

  • getting back a return value like we have been getting for weeks in C and Python.

  • Now, there is nothing on the left hand side.

  • I'm not waiting for a return value, per se.

  • I'm certainly not storing a return value on the left hand side,

  • as we've been doing for ages with Python and C.

  • Instead, I'm passing in a function, functionality,

  • like my telephone saying, call me back when you have the answer.

  • And that's the paradigm now that's really starting to change for us.

  • And there's a couple of other things we can do along these lines, too.

  • Let me open up one, which is just a little silly.

  • But it kind of brings me back to my days of HTML.

  • Back in the day, in HTML like 1.0, there was this amazing tag called blink.

  • Whereby, if you did open bracket blink close bracket

  • and then wrote some words and then close the tag,

  • it would just do this on the web page.

  • And I'm pretty confident this is how you were greeted

  • when you visited my like freshman year website or sophomore year website like,

  • hello, welcome to my website.

  • This is stupid.

  • And eventually, the one good thing the standards bodies did over the years

  • was remove blink functionality all together.

  • There was also, as an aside, a marquee tag, where, just like a stock ticker

  • or like a Broadway show marquee, it would just

  • scroll text across your screen like this, which is also pretty stupid.

  • But we can bring back at least the blink tag as follows.

  • So here is a pretty simple web page with just a single div and an ID

  • of greeting, just so I have some way of uniquely identifying it.

  • And suppose I want to make this text blink.

  • Well, if you consider, now that you have the ability

  • to execute code on the user's computer, we

  • should be able to achieve this by like turning CSS on and turning CSS off,

  • on and off.

  • And you might not have done this before.

  • Because we've probably just used CSS for like centering text or making it

  • bold or a color or a different size or the like.

  • But you can also make it display or not display, visible or invisible, too.

  • So if we look at my script code, here, for better or for worse,

  • let me consider how I might do this.

  • I'm going to go ahead and define a function called blink

  • that simply gets that div by its ID.

  • We've seen that before.

  • And then I just do this.

  • If the div's style property, and you would only

  • know that this exists by seeing it in class or reading in a manual

  • or seeing it online, if this div, which came from this line,

  • has a style of visibility equal to hidden, then use this line of code

  • to change the visibility for that style of that div to quote unquote "visible."

  • Else, logically, if that div style is visible change it to hidden instead.

  • To this day, I do not know why the opposite of visible is not invisible.

  • It is hidden.

  • But that is also a design decision we're stuck with.

  • So how does this work?

  • This is just one function that just changes the state.

  • But something's not going to blink unless you change

  • and then change and then change and then change.

  • Well, another beautiful feature of JavaScript

  • that we're kind of using for evil here is to do something repeatedly

  • but asynchronously.

  • I could easily make something blink and blink

  • and blink by just making an infinite loop.

  • But if I had an infinite while loop or for loop,

  • I would, by definition, never get out of it.

  • And therefore, the page would blink forever,

  • but the page would not do anything else.

  • But with asynchronous code like this, I can register a function with a browser

  • and say browser, go ahead and call this function every 500 milliseconds.

  • And notice, this is one line of code.

  • So when the browser executes this code, it executes one line.

  • And it just keeps going.

  • But it remembers, every 500 milliseconds remember to stop whatever it's doing,

  • blink, then keep going, then blink, then keep going.

  • So in this way, can you have multiple things happening on your web page.

  • Because the way JavaScript works is it itself,

  • the language, built into the browser, essentially,

  • just itself has this infinite loop.

  • And it's constantly listening for users to click on things.

  • It's constantly listening for the mouse to move.

  • It's constantly listening for a timer to go off.

  • And every time one of these events happens,

  • it dispatches the handler, the function, that it was told

  • to call in response to those events.

  • So the end result here with blink is this.

  • If I go back to my directory index, here, and open up blink.html,

  • you see it doing exactly that.

  • And I can tweak this a little differently.

  • If I want to do it every tenth of a second, we can do this.

  • And if we do this too fast it's probably not healthy.

  • So we'll just leave it at 50.

  • So you know, this is how I learned how to make the web years ago.

  • So what more can we do in a more compelling way?

  • Let's look at one final example that I fixed during the break, which

  • is this here map.

  • This is where the world starts to get really, really interesting.

  • Because there are so many third party APIs out there,

  • application programming interfaces.

  • Like nice people and nice companies who are trying to sell you services,

  • they have features, code that they've written that they make available

  • on the internet for us to use either by grabbing data from them,

  • as in the case of CS50 Finance pulling in stock quotes.

  • Or in the case of Google Maps, actually baking in additional functionality

  • to your application, so you don't have to implement it yourself.

  • If anyone's ever used Lyft or Uber on your phone,

  • Lyft and Uber did not start out by being map companies,

  • sending cars all around the world mapping the whole world.

  • That would be insane for a startup to try to do that.

  • They wanted to build a car sharing service

  • on top of another feature that's just kind of a necessary ingredient.

  • So they used Google or some other company,

  • paid them some amount to build their maps into their own application.

  • And then they contribute to their own intellectual property and ideas.

  • So how can we do this?

  • Well, it turns out if I have a web page that's pretty simple,

  • and let me go ahead and just quickly delete this real fast,

  • so that it just looks as follows.

  • Here is a very simple web page that's got a body and then

  • a div inside of it whose ID is map.

  • And then at the very bottom of the file notice

  • that there's this JavaScript code that points specifically

  • to Google API, application programming interface, slash map slash something.

  • And what I did during the break was I downloaded a new API key,

  • which allows me, David Malan, to use their API so that all

  • these requests are associated with me.

  • Previously, I had an old key.

  • So it just wasn't working.

  • And that's why we got the error message.

  • So I signed up now for a free API key.

  • But how do I actually do something with this map?

  • Well, we can do a few different things simply

  • by following along with the documentation online in the right way.

  • Let me go ahead and open up the following here.

  • If I go ahead and load this page right now, that I've deleted that code,

  • and open up map.html, there's nothing there.

  • It's just a big white page.

  • And that's because I haven't added any of my own code.

  • But if I go into the script tag here, let me go ahead and do the following.

  • Let me define a function called initMap that takes no arguments.

  • And then inside of this function, let me go ahead and do this.

  • Let me declare a variable called map that takes on the value of a new

  • google.maps.map of document.getElementById("map") And then

  • pass into that a special object.

  • So we'll see what this means in a moment.

  • The syntax here is a little funky.

  • But this line of code I only knew by reading

  • the documentation for Google Maps.

  • Google Maps told me if you want a new map, type this.

  • And if you want to remember that map in a return value or in a variable, sorry,

  • I should have said let, store it in map on the left.

  • So the weird thing here is the following.

  • The two arguments are these.

  • This is a line of code that we have seen before that says, hey browser,

  • go get me the HTML element from the dom whose unique ID is map.

  • What is that element?

  • It's just this div.

  • And it's empty.

  • There's no map there now, obviously.

  • There's nothing between that close brace and open brace.

  • So that's why there's no map.

  • But this line of code is what we're going

  • to use to inform Google where to put its map for me.

  • It takes another argument here, as per the curly brace

  • and the close curly brace, which is just an argument, which

  • is to say the documentation told me I have to pass in multiple key value

  • pairs.

  • I have to configure the map.

  • So let me do that in just a moment.

  • Let me go ahead, now, and reload the map by going up to the browser and reload.

  • And interesting, it's not doing anything yet.

  • But we did get progress, right?

  • It's gray.

  • But that suggests I just haven't configured the map.

  • So let me do that.

  • And I would know this only from the documentation

  • that I need to provide a key of center.

  • And that center needs a latitude and longitude.

  • And I can choose just to be neutral here, 39.833

  • and a longitude of negative 98.583 close curly brace.

  • And then a zoom key of 4.

  • These mean nothing out of the context of Google.

  • I know this only from reading the documentation.

  • And Google's documentation told me make sure you use a key called center.

  • Have its argument after the colon be another JavaScript object

  • with two keys, lat and long, each of which

  • is exactly that, a float that represents a latitude and a longitude.

  • And then also tell me, the Google API, what zoom level do you want.

  • Do you want to see the bird's eye view way up here?

  • Or do you want to really zoom down on the terrain?

  • And 4 is roughly, it's at a certain level that's useful.

  • But we can tinker with that as well.

  • Let me save that.

  • Go back over here and reload the page now and voila.

  • I'm centered over what's roughly the center of the United States

  • at a certain zoom level.

  • If I want to change one of those values just to see,

  • let's make this maybe 8, save.

  • Reload.

  • Now I'm really zoomed in on what appears to be Kansas or Nebraska.

  • So that's a different zoom level.

  • I can really kind of poke around the world, so to speak.

  • So let's see, if I go to like 139, let's see where that takes me.

  • Reload.

  • That might not be geographically possible.

  • Let's do 42, how about.

  • Change that to 42, reload.

  • Now we're over, OK, Sioux City there.

  • Let's maybe go to 44.

  • Anyhow, we're moving the map to places that I don't know in advance.

  • Now we're in South Dakota.

  • In any case, all we have done now is just configure

  • the map to be in different places.

  • But there's other functionality in Google Maps.

  • Let me revert this and let me go ahead and declare a couple of other things.

  • I can actually declare a marker, as follows.

  • Let me get myself a new Google Maps marker, open paren and then

  • close paren.

  • And then notice I have a curly brace in there, too.

  • Because marker is another feature of the Google Maps API

  • that lets me specify on what map I want to put the marker.

  • So there's a key called map.

  • And then coincidentally, there is a variable called map,

  • which I defined up here.

  • And then it takes one other thing, the position of this marker.

  • Well, I'm going to put this marker at latitude 42.3762

  • and a longitude of negative 71.1158.

  • And then just for good measure, let's do one more of these.

  • And actually, I don't strictly need the variable here.

  • So I'm just going to get rid of that.

  • And I'm going to do a new Google Maps marker.

  • Same syntax as before.

  • The map is going to be the same.

  • But the position of this marker is going to be a latitude of 41.3104

  • and a longitude of negative 72.9289 close curly brace, save.

  • And if I didn't screw up, which I did.

  • And it's yelling at me.

  • Unexpected token param-- oh, OK, forgot this.

  • Save.

  • Go away.

  • Go away.

  • Reload.

  • Let's go and zoom out.

  • And look at that.

  • We have markers over what is hopefully Harvard and Yale.

  • And so where did all this come from?

  • Well, literally Google Maps.

  • And that's what I Googled during the break, API key.

  • Google Maps API.

  • And if I go to this URL, as you soon will too,

  • you'll see under its documentation that they

  • have many different APIs, some of which are for phones, some of which

  • are for web pages such as this, the JavaScript API.

  • And you'll see that there's a very rich interface for actually creating

  • these kinds of maps.

  • And the documentation, frankly, can be a little overwhelming at first glance.

  • But here they give you examples of how to put a marker, for instance,

  • over Australia.

  • This is how I inferred how to put one over Cambridge, Massachusetts and New

  • Haven.

  • There's other functionality, too.

  • Like these things called info Windows.

  • So with info Windows, if I scroll down to this example here,

  • you'll be able to add clickability.

  • So if I register an event handler that's not on submit but on click,

  • I can do things like this, just as Google has,

  • whereby on clicking a marker, we trigger something else to happen,

  • in this case, an info window to open, and thereby get functionality.

  • And so to bring all of this together, which you will do, ultimately,

  • for CS50's mash-up problems set, your very last,

  • is to implement a user interface using some of these building blocks.

  • Here we are centered over Stanford, California.

  • And notice that the map is full screen.

  • But you can zoom in and out down there.

  • Notice that there's a text box, which is a very simple HTML

  • form at the very top.

  • And notice, just as I did before, we have configured the staff solution,

  • as yours will soon do too, to listen for clicks and on clicks,

  • call a function that makes an AJAX request to a server,

  • get back some news articles, create an unordered list out of them,

  • and display them in one of these info windows.

  • And so if we actually look at what's going on underneath the hood,

  • let me go to my developer menu, under developer tools.

  • And as you should be in the habit, again, watching your network tab,

  • let me go ahead and do exactly this.

  • Let me clear that, click Palo Alto's news, California.

  • And notice a few things just happened.

  • One, my browser made a request to an articles route,

  • passing in the geography of this zip code here.

  • Notice that I got back some gifs here.

  • And in fact, the internet here is so fast, we didn't see the progress bar.

  • But we would have seen a little spinning indicator if the internet were slow.

  • And that's how I then got those news results.

  • And if I click on the articles here, notice what I'm getting back is--

  • OK, hello.

  • Always check the day's news before class.

  • So what I see here is a big JSON object.

  • And it's all in one line.

  • So it's a little hard to see.

  • But I'm sure you can scroll through the news

  • later and see actually what the articles and the URLs thereof are.

  • But there's one more piece of functionality.

  • All of us have seen auto-complete work in our browsers,

  • because it remembers usually what you've previously typed.

  • But it's more powerful to autocomplete based

  • not on just what the users typed in the past, but what you think in the future

  • they might be typing.

  • So if I actually want to search for 02138,

  • notice I can narrow down the list of all the cities in the US so that I can

  • click on that autocomplete.

  • And now we have a localized map to the Cambridge area

  • where I can get the local news from our area.

  • Or I don't have to search just by zip code,

  • I can type in New Haven, Connecticut and get any of New Haven's zip codes

  • and similarly teleport over there.

  • So among the challenges ahead is to download a pretty big file, a text

  • file, called us.text, in which are bunches of cities names and states

  • and zip codes, import those into your own SQL-like database,

  • implement a few routes so that you can ask your database what

  • are the few cities within view and what is the current news in this area,

  • and then using JavaScript and today's ideas, stitch all of this functionality

  • together to mash up all of these different ideas into an end result,

  • your last.

  • And that's it for today.

  • I'll stick around for questions one on one.

  • Otherwise, we'll see you next time.

[MUSIC PLAYING]

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

B1 中級 美國腔

CS50 2017 - 播放11 - JavaScript (CS50 2017 - Lecture 11 - JavaScript)

  • 26 5
    小克 發佈於 2021 年 01 月 14 日
影片單字