Lecture 05 - JavaScript Fundamentals
Lecture 05 - JavaScript Fundamentals
HTML and CSS are markup languages, used to annotate websites to describe
their meaning and appearance.
But they are not “full” (i.e., Turing Complete) programming languages—they
don’t have variables, control structures, or other features required for the
computer to execute an algorithm.
The interpreter will read and execute one line of code at a time, executing that
line before it even begins to consider the next.
This is in contrast with compiled languages like C or Java that have the
computer do the translation in one pass (at compile-time), and then only
execute the program after the whole thing is converted to machine language.
This on-the-fly translation means that interpreted languages like JavaScript are
usually slower than compiled languages, but not enough that we’ll notice (web
browsers include highly optimized interpreters).
The bigger drawback is that without the compile step, program errors appear
at runtime rather than compile time, making them more difficult to catch and
fix.
As such, JavaScript developers make heavy use of various linting tools (which
flag common problems that can lead to runtime errors), as well as automated
testing systems to check against a variety of inputs.
Although JavaScript was designed for and is most commonly used within web
browsers (which contain their own JavaScript Interpreters), it can also be
executed on the command line by using Node.js, allowing JavaScript to be a
fully general language.
In the Browser
JavaScript scripts are most commonly executed in a web browser as part of the
browser rendering a web page.
Since browsers render HTML content (in .html files), JavaScript scripts are
included in that HTML by using a <script> tag and specifying the relative path to
the a file containing the code (usually a .js file) to execute.
When the browser renders the HTML (reading top to bottom) and gets to that
tag, it will download and execute the specified script file using the JavaScript
interpreter:
Notice that the <script> element is not empty! It is possible to include JavaScript
code directly inside the tag, but this is considered bad practice (keep concerns
separated!) and should only be used for quick tests.
Most commonly it is either placed in the <head> in order for the script to be
executed before the page content loads, or at the very end of the <body> in
order for the script to be executed after the page content loads (and thus allows
the JavaScript to immediately interact with the loaded HTML elements).
We will (begin by) most commonly be putting <script> tags at the end of the
<body>:
Most browsers also support adding a defer attribute to the <script> element that
tells the browser to defer downloading and running the script until the page is
fully loaded and rendered to the screen.
With this attribute, you can put the <script> element in the <head> without any
issues.
While JavaScript most commonly is used to manipulate the web page content
and is thus pretty obvious to the user, it also can produce “terminal-like”
output—including printed text and error messages.
With Node installed on your machine, you can use the node terminal command
to start an interactive Node session.
This will allow you to type JavaScript code directly in the terminal, and your
computer will interpret and execute each line of code:
You can enter one line of code at a time at the prompt ( > ).
This is a nice way to experiment with the JavaScript language or to quickly run
and test some code.
You can exit this session by typing the quit( ) command, or hitting ctrl-z
(followed by Enter on Windows).
Note that the JavaScript console in the Chrome Developer tools provides the
same interactive functionality.
It is also possible to run entire scripts (.js files) from the command line by using
the Node command and specifying the script file you wish to execute:
This allows you author entire programs in JavaScript (e.g., writing the code using
VS Code), and then executing them from the command line.
This process is more common when doing server-side web development (such as
implementing a web server using Node), but we will still use it for practice and
testing.
Unlike Java or C, JavaScript has no main( ) method that “starts” the program.
Each line can declare a variable or function, which will then be available to the
next statement to use or call.
Thus with a JavaScript program, you should think of the sequence of steps you
want to be performed, and write lines of code in that order.
In a way, you can think of the entire file as the “body” of a main( ) method…
except that this body will contain further function declarations.
For example:
As in Java, each statement should end with a semicolon ( ; ) marking the end of
that statement.
Strict mode is more “strict” about how the interpreter understands the syntax:
For example, in strict mode the interpreter will produce an Error if you try and
use a variable that has not yet been defined, while without strict mode the code
will just use an undefined value.
This means that variables are not declared as a particular type (e.g., int or
String), but instead take on the data type (Number, String, etc.) of the value
currently assigned to that variable.
As we don’t specify the data type, JavaScript variables are declared using the let
keyword:
This is somewhat similar to null in Java (though JavaScript also as an null value
that is not commonly used):
Note that the let keyword is in fact new syntax introduced with ES6: older
versions of JavaScript used the var keyword.
The difference is that variables declared with let are “block scoped”, meaning
they are only available within the block (the { }) in which they are defined.
Variables declared with var, on the other hand, are “functionally scoped” so are
available anywhere within the function in which they are defined.
This means that you could declare a variable within an if block, and that
variable would continue to be available outside that block! Thus let allows for
cleaner, more efficient code, and with less bugs.
Along with let, JavaScript variables can also be declared using the const
keyword to indicate that they are constant (similar to what the final keyword
does in Java).
Numbers are used to represent numeric data (JavaScript does not distinguish
between integers and floats).
As with Java, JavaScript strings are immutable, so most string methods return a
new, altered string.
Booleans (true and false) in JavaScript work the same way as in Java, can be
produced using the same relational operators (e.g., <, >=, !=), and support the
same logical operators (e.g., &&, ||, and !):
Note that it is possible to assign a value to any index in the array, even if that
index is “out of bounds”.
This will grow the array (increase its length) to include that index—intermediate
indices will be given values of undefined.
The length of the array (accessed via the .length attribute) will always be the
index of the “last” element + 1, even if there are fewer defined values within the
array.
Arrays also support a variety of methods that can be used to easily modify their
elements, similar to the ArrayList class in Java: