Fred
Brack Raleigh, NC |
Along with HTML and CSS, the JavaScript programming language is considered a "core technology" of the World Wide Web (read websites), driving many web applications. The code can be as simply as providing the current 4-digit year ( ... as determined here and now by JavaScript), because HTML can't do that, or as complex as gathering user input to display detailed data from a database or another web page.
This is not a full tutorial on the language but rather an introduction and reference to many of its features along with some ideas as to how you can get started experimenting on your own. Want a free full tutorial? Try Learn-JS, which helped me, and JavaScript.info is a great teaching aid or reference. And I do love W3Schools. They all have more examples than I offer (I try to be concise!). I created this series of JavaScript web pages (see the index at the bottom, which you may want to bookmark) to help me document my own understanding of the language as I progressed from novice to intermediate user ... and because I like to document stuff for others! I will come back to it often as a reference document. I hope you find it useful. (And BTW, I keep updating it ...)
The starting point for any programming language is how you declare variables (named containers for storing data values). In JavaScript there are four basic types of variables:
Technically there are five other types of variables: undefined (declared but uninitialized); null (an empty object pointer); function (actually objects, and discussed below); BigInt (for very large integers - fairly new and not necessarily supported); and symbol (fairly new and complicated...). I have no plans to mention BigInt or symbol; function is important (though it is hard to think of it as a variable); and you will find occasional references to null and undefined.
If you want to test for the type of variable, you can use the typeof operator. It returns the type name of a variable, such as string or object. You should be aware of three oddities, however!
- Unlike most other names in JavaScript, it does not use camelCase (discussed below under Properties and Methods). You would normally expect it to be written typeOf, but it is not.
- You can specify it in two different ways:
typeof myvar
typeof(myvar)- It returns an incorrect name for null! The typeof null is "object". This "error" was introduced at JavaScript's creation and has never been remedied. (Note: setting a variable to a null or empty string, as in "" is not the same a setting it to null ...)
Each variable name must begin with an alphabetic character (almost always lowercase, but uppercase permitted), or far less common a dollar sign or an underscore.
How to assign a variable gets interesting, as you must take scope into consideration. There are four ways to do this.
Note that while you can use var in a function (defined below), its scope will still be local. However, if you use var within the braces of an if statement (also defined below), it will be global...
We interrupt to introduce the semicolon, which is used as a statement-end character. While not required, it is highly recommended, and we will show it from now on. |
Note that in each case above, the type of pi (no pun intended) is number. However, you could also say:
var pi = "3.14";
which would have a type of string. In fact, you could redefine the variable pi in this manner, thus changing its type to string.
To assign a hexadecimal number, you use this notation, where the hex values A-F can be upper- or lower-case:
var hex26 = 0x1a; // that is, 26 in hex is 1A
You can define multiple variables on one line, if you wish, separating them with commas, or even split the definition between lines:
var a = "alpha", condition = true, pi = 3.14; let a,b,c = 0; // BUT NOT THIS!
While I don't intend to cover objects in this introduction (see JavaScript Objects), here are two examples of object definition:
array = [ 1,2,3 ]; object = { firstName:"Fred", lastName:"Brack" };
Brackets* define an array, while braces* define an object. Arrays are a type of object, though. Non-Array objects consist of propertyName:value pairs as shown.
In many cases, programmers will simply declare a variable without setting a value, or create a null value in a format which implies what the type is. Examples:
var counter; // name it what you like, but it is undefined for now! var name = ""; // string var model = {}; // object var list = []; // object, but with the special characteristic of array
* Technically, brackets can be used to get to individual characters in strings, and braces also define blocks of code, such as used by functions or if statements, but that is not the point being made here!
There is one special way to declare variables called template literals which are enclosed by the backtick (`) character. One purpose is to allow easy definition on separate lines, while the other purpose is to allow variable substitution within the string. Examples, which both produce the same results on three lines:
var text = `Part One: Introduction to JavaScript by Fred Brack`; var part = "One"; var title = "Introduction to JavaScript"; var text = `Part ${part} ${title} by Fred Brack`;
Other than template literals (above), there are two ways to continue your input on additional lines. In the first case (using a + sign at the very end of the line), the plus-sign acts just like it would on a single line (doesn't add any blanks, for example); but because it hangs out alone at the end of the line, the processor knows you will be continuing your input on the next line. In the second case (using a \ or backslash at the end of the line, blanks count!
var name1 = "Fred " + "Brack"; var name2 = "Fred " + "Brack"; // name1 and name2 are identical var name3 = "Fred \ Brack"; // name3 is identical to name1 and name2; the space before the \ is remembered var name4 = "Fred \ Brack"; // but name4 comes out as "Fred Brack"
Ideally a programming language does not have any "reserved words" -- words that you should not use for variable names, for example. That said, it makes for better readability of your code if you don't intermix words otherwise found in the langauge with your own choice of variable and function names.
I have compiled a list of JavaScript Reserved Words and Words to Avoid (click the link for a PDF) from various sources, since no source we found was complete. Arguably, some of the words have been removed from the list in the latest language standard, but we leave them because not every browser has full support, and because they make sense (like "boolean" and "char"). You will note that some of the words (like "Date") are capitalized, so you could use an all lowercase version ("date"), but that doesn't seem like a good idea either. (By convention, people seem to use dt if they want to set a date.) In general, avoid using any "word" you have seen elsewhere in the language -- which is why this list goes beyond the full list of only reserved words.
The basic arithmetic operators are exactly what you would expect:
Like some other languages, JavaScript allows two additional arithmetic notations to automatically increment or decrement a variable by 1:
Example:
var x = 5; x++; // x now equals 6
We interrupt to introduce the double-slash
(//), which is used to begin a COMMENT on a single line. You can also start a comment with /* and end it on the same or a different line with */. |
This is a bit more complicated than it looks, as we have prefix and postfix notation. If the increment or decrement notation appears before the variable (prefix), the increment is done before using it in an equation. If it appears after the variable (postfix), the increment is done after using it. Example:
var x = 5; var y = ++x; // now both x and y = 6 (because x was incremented before assigning to y) var z = x++; // now x = 7 and z = 6 (because x was not incremented before assigning to z)
Please note that the plus sign (+) means two things: add versus join. For numbers, it means add. For strings, it means join. If you combine strings and numbers, they will both be treated as strings.
var x = 5; var y = 6; var z = "7"; // (string) x+y; // = 11 (number) x+z; // = 57 (string) 1+x+z; // = 67 same as (1+x)+z (string) 1+(x+z); // = 157 (string) "Hello"+" "+"there"; // = "Hello there" "Hello "+"there"; // = "Hello there"
When you want to get beyond "basic" arithmetic, you need the JavaScript Math object, which we are not going to discuss in this tutorial except to give this brief example. For a complete list of Math functions, including trigonometric, visit w3Schools Math Reference.
Math.PI; // returns 3.141592653589793 Math.round(9.7); // returns 10 Math.trunc(9.7); // returns 9 Math.abs(-5); // returns 5 Math.max(-1,3.3,10); // returns 10 Math.min(-1,3.3,10); // returns -1 Math.random(); // returns a number between 0 and 1
Logical operators are typically used in IF statements (discussed below), but they can be used in many places. An expression is evaluated and returns a Boolean value of true or false. The logical operators are used within the expression to create a simple or complex comparison which is ultimately either true or false. Here is the basic set of operators:
Note from experience: you will forget that you must use a double equal sign many times; so when your JavaScript fails, look for this problem!
There are a few additional operators:
x = 5 y = "5" x==y // true x===y // false
var var1; // undefined var var2 = "" // effectively null var var3 = 300; var var4 = 400; var answer = var1 || var2 || var3 || var4; // = 300
// Format: ( condition ) ? if-true-value : if-false-value canDrink = (age >= 21) ? "Yes":"No";
So how do you get started "playing" with JavaScript to test your knowledge? I would suggest that you use a JavaScript simulator. The one I'm using is located at https://www.webtoolkitonline.com/javascript-tester.html, but there are others.
This simulator will flag JavaScript syntax errors as soon as you type a line. But how do you see the values of your calculations? The simulator will automatically display the result of the last statement if you don't. Another method is to use the alert function (technically part of the Browser Object Model). It displays results in a dialog box the only operand of which is OK to dismiss it. The operand of alert is whatever you want displayed. You can combine items to be displayed with plus-signs (+). This would allow you to name a variable, for instance, and show its value. One caveat: no blanks are included by default, so include any blanks in your quoted string. Example:
x = 5; alert("The value of x is " + x); // The spaces around the plus sign are optional and do NOT result in blanks in the output // The trailing blank after "is ", however, within the quotes, is honored!
Alternatively, if you want to create your own HTML page for testing, you can get greater value out of using what's called the debugging console and the console.log function. (Note: Ctrl-Shift-I will bring up the debugging tools page, from where you can select Console. Some browsers, like Mozilla, let you go directly to the console with Ctrl-Shift-K; but very nicely, F12 usually works for this purpose on a Windows computer, or Cmd-Opt-J on a Mac.) Create a web page with the following content, observing that all your JavaScript code will be placed within <script>...</script>.
<p>Test JavaScript</p> <p>Results are generally visible in the CONSOLE (F12 or Cmd-Opt-J on a Mac).</p> <script> console.clear(); // this simply clears the console screen // place your JavaScript statements here ... ... console.log(...your message and/or variables here...); // format same as alert </script>
Now add your JavaScript statements and either publish the code to test or invoke it directly from a web browser. (I use Microsoft Expression Web's SuperPreview function for this purpose.) With each change you make, refresh the page after saving and try again. Exactly how you invoke the debugging console can vary from browser to browser.
To see a list of all the possible debugging options available with the console function, view my JavaScript: Using the console Object document. You can even cut-and-paste the code from there to try out ... as you can cut-and-paste any of my examples in this course to try out.
I should mention that I like to simplify displaying my results during testing by using my own function say, as in say("The value of x is " + x). The definition of say will vary depending on how you test. You can use any of the following definitions depending on how you are testing!
// Use this one anywhere function say(msg) { alert(msg) } // Use this one anywhere you bring up the debugging console (F12 or Cmd-Opt-J on a Mac) function say(msg) { console.log(msg) } // Use this one with https://www.webtoolkitonline.com/javascript-tester.html function say(msg) { var screen = document.getElementById("screen"); var div = document.createElement("div"); div.innerHTML = msg; screen.appendChild(div); }
Did you happen to notice there was no statement-end semicolon after the function definitions above? This was not an oversight! By convention, semicolons are not required after code blocks {...}. |
Since a tutorial on all the variations of creating a JavaScript function would be quite long, I just want to give a basic definition so you will be better prepared when you look at examples or use existing functions. A JavaScript function is similar to a subroutine in other languages and is considered a method in JavaScript. It takes zero or more operands and then has instructions to determine what to do with them before returning. Because functions are objects, their definition is bounded by braces. You are required to include a pair of parentheses after the function name, regardless of whether or not any variable names appear within for passed values. By convention, function parameters are separated by a blank. For example:
function funcname ( parm1, parm2 ) { // function code to be executed }
The function definition can appear anywhere in your code and doesn't even have to fall prior to first invocation (though typically it does). Placing the function definition "at the bottom" parallels how subroutines are placed in other languages. The reason this works with JavaScript is called hoisting, which effectively moves function (and variable) definitions to the top of your code prior to execution.
When a function is invoked, the statements inside the function definition will be executed. Remember those variables defined with "var"? Their values will be available to the code inside the function. But inside the function, you will probably define any local variables (that is, local to the function) with let (meaning they have block scope), which is also true of how parm1 and parm2 are handled in the function (meaning that any changes to them will not be reflected back to the caller). Here is an expanded example of our function:
function addem (parm1, parm2) { let text = "The answer is "; let answer = parm1+parm2; return text+answer; } alert(addem(2,3)); // this will return "The answer is 5" // outside the function, text and answer are undefined
In case you are wondering, you could eliminate the first two lines of the function and replace the last one as follows:
return "The answer is "+(parm1+parm2);
It is worth noting, however, that the parentheses are required to let the mathematical addition be performed! Without those parens, the answer would be 23 because the first item in the list was a string; so parm1 and parm2 would be treated as strings. Also note that no semicolon is required after the closing brace on a function definition. And another thing: the return statement stops execution of the function; it does not have to appear last; and you might have multiple return statements in branches of your function. Any operand of return is returned as the value of the function. If you run off the end of the function without a return statement being executed, the result is "undefined."
And yes, you might invoke the function in this manner:
sum = addem(2,3);
That should be enough to get you started on experimentation!
Oh wait ... I really don't know where to cover this conveniently, so I'm going to mention arrow function expressions here, because I use them a few times in later examples. They are a shortcut for some -- I repeat -- some function definitions. You should read the complete Mozilla definition of arrow functions to understand the exceptions. The gist is that you can shorten a function definition by leaving out some components in a shorthand notation. Example, using our addem function:
addem = (parm1, parm2) => "The answer is "+(parm1+parm2); addem(2,3) // = 5
By way of explanation, the word "function" is missing; an = sign was added between the function name and its arguments; the braces have been removed and replaced by the notation =>; and the return statement is gone because it is implied. If more than one function statement was required, the braces would be required too. If you only had one parameter, the parentheses would not be required.
add10 = parm => "The answer is "+(parm+10);
A control structure is a language feature that allows you to control (alter) the normal course of execution. The classic example would be an IF-THEN-ELSE structure, which is called a conditional statement. IF a condition is true, THEN you do something; but if that condition is not true (i.e., false), then you (optionally) do something ELSE; thus IF-THEN-ELSE. For some unknown reason, however, the JavaScript developers decided not to use the classic THEN word, and they implemented the conditional statement structure like this, with the THEN implied:
if (condition) { // block of code to be executed if the condition is true } else { // block of code to optionally be executed if the condition is false }
The important thing to note here is that the condition must be contained in parentheses. It can be simple (i<5) or as complicated as you wish (with ands and ors or calling a function). Note also that unlike other programming languages, JavaScript does not allow the word "then" to appear after the if. [It would have been so easy for them to allow this ...] If the "block of code" turns out to only be one statement, you may wish to put it on the same line as the IF or ELSE. Technically in this case the brackets are not required; but good coding practice should cause you to use them anyway. Here are examples of if statements:
if (n==0) { do this ... } // NOTE THE DOUBLE == !!! if (n<0 || n>9) { // NOTE THE DOUBLE || !!! do this ... and this ... }
And here is how you add the ELSE statement:
if (condition) { statement to be executed if the condition is true } else { statement to optionally be executed if the condition is false }
You can also insert an ELSE IF in the middle of the IF-THEN-ELSE sequence as many times as you wish. For example:
if (condition) { statement to be executed if the condition is true } else if (condition2) { statement to be executed if condition2 is true } else if (condition3) { statement to be executed if condition3 is true } else { statement to be executed if none of the previous conditions are true }
Be sure to read below about how to prematurely exit your blocks of code early with break and continue.
NOTE: An alternative to IF-THEN-ELSE is the SWITCH statement, which we are not going to discuss. It has some cautions associated with it. For more information on switch, visit w3schools.
There are several variations of FOR, some of which will be discussed later under arrays and objects; but the basic FOR statement looks like this:
for (stmt1; stmt2; stmt3) { // code to be executed }
where:
So the idea is that you initialize the loop with stmt1, you increment some value with stmt3, and you continue execution of the loop if the condition in stmt 2 is satisfied. Example:
for (i=1; i<5; i++) { alert("i="+i); } alert("i="+i+" after loop ends");
In the above example, the variable i is initialized to 1 at the start of execution and incremented by 1 at the end of the loop. Execution continues until i reaches 5 (i<5) at entry into the loop, so the loop does not execute for i=5; however, i does equal 5 after the loop ends (something you might want to test for to find out if the loop continued without premature termination).
Premature termination? That would be the BREAK statement ("LEAVE" in other languages), as opposed to the also optional CONTINUE statement ("ITERATE" in other languages). By testing conditions within the loop, you may wish to terminate (drop out of the loop) early (i.e., you found what you were looking for), thus BREAK; or you may wish to continue looping without doing something else on this pass through the loop, thus CONTINUE.
for (i=1; i<9; i++) { if (i%2==1) { continue } // skip odd number if (i==8) { break } // exit when we reach 8 alert("i="+i); } alert("i="+i+" after loop ends"); // = 2, 4, 6, then shows 8 after the loop
WHILE is a simplification of FOR because it acts like FOR with smts1 and stmt3 absent! You just have stmt2, which is the condition which will cause the loop to execute. However, you must remember to establish the tested variable first and increment it within the loop!
while (condition) { // block of code to be executed }
var i = 1; // essential to prime variable i while (i<5) { alert("i="+i); i = i+1; // essential to increment i within the loop!!! } // = 1, 2, 3, 4
DO-WHILE, on the other hand, is a variation of DO UNTIL in other languages. You DO first, then test for WHILE at the end of the loop, thus guaranteeing that the loop will execute at least once. As before, you must establish and increment whatever variable is tested in the condition. I personally find this a bizarre structure, with the WHILE at the end ...
do { // block of code to be executed } while (condition);
i=1; do { alert("i="+i); i++; } while (i<5); // = 1, 2, 3, 4
I said we weren't going to discuss JavaScript objects in this introduction because that is a HUGE area. However, to understand better how to read JavaScript and use elementary features, we should touch on these two primary characteristics of objects: properties and methods.
It turns out that even though properties and methods are object features, they can be used with non-object values (called primitive values) too. For example, length is a property of a string variable, and indexOf is a method to find the position of a value within a string. You invoke properties and methods by suffixing a variable name with a period, followed by the property or method name. Methods require parentheses, even if you are not passing an operand. Examples:
fullName = "Fred Brack"; lthOfName = fullName.length; // = 10; length is a property posOfBlank = fullName.indexOf(" "); // = 4 (starts with 0); indexOf is a method alert("The length of " + fullName + " is " + lthOfName); // = ... 10 alert("The blank is found at position " + posOfBlank); // ... 4 (remember, numbering starts at 0) alert("The first name is " + fullName.substr(0,posOfBlank) + "."); // = ... Fred; substr is a method
We interrupt to discuss names. JavaScript is unforgiving if you don't use matching or proper capitalization in names. This includes variable names, function names, property and method names. For example, above you cannot say "indexof" (instead of indexOf) or reference "fullname" (instead of fullName). You WILL make these errors ... often! And this is as good a time as any to point out that standard practice is to begin variable or function names with a lowercase letter and capitalize any word changes (also known as camelCase), as in indexOf or fullName. |
To learn more about strings and their methods as demonstrated above, see JavaScript Strings next. You can even cut-and-paste the code from there to try out.
Like Objects, the DOM is a huge area which won't be discussed yet (see The Document Object Model); but you at least need to know what it is. The Document Object Model is how JavaScript communicates (reads and writes) with your HTML. The World Wide Web Consortium (W3C) defines it this way:
The W3C Document Object Model (DOM) is a platform and language-neutral interface that allows programs and scripts to dynamically access and update the content, structure, and style of a document.
Using the DOM structural notation, you can essentially alter anything on an existing web page, though in some cases you will need to identify areas by using an "id" tag on HTML tags (e.g., <h2 id="head2">Heading</h2>. Your JavaScript will then reference that id to alter the characteristics or content of the heading. As elsewhere in JavaScript, the DOM has properties and methods. A property would be an existing HTML element (like our example) where you want to get or set a value. A method would be an action you take, like inserting or deleting some HTML.
The most elementary thing you should understand about the DOM is how you can insert some HTML on your web page right at the point where your JavaScript is running. Basically everything in the DOM starts with the word document (the object name) followed by a period and the property or method. To insert (write) some HTML in your document, you use the document.write notation followed by whatever HTML you want inserted. Example:
newhtml = "<p>This is new.</p>"; document.write(newhtml);
Obviously you can use your JavaScript to dynamically create whatever it is you are going to write, and it can be as small as the current year or as large as the entire body of the document. This introduction to the DOM was just to get you to the point where you could write something in your testing HTML, but it is just the tip of the iceberg!
The Browser Object Model (BOM) represents the browser in use as opposed to the document (HTML) on the page. The Browser Object Model is how JavaScript communicates (reads and writes) with your browser. It has multiple components, such as information about the device in use, the physical screen, and the current window.
Many references officially begin with the object name window, though in many cases "window" can be dropped. Everything in JavaScript is a member of the window object. An example of a window method would be causing a new browser window to be opened: window.open(url). The following subcategories exist: screen, location, history, navigator, popup alert, timing, and cookies. In some cases those words (or related words) must be preceded by "window.", while in other cases they can stand alone. The popup alert "alert" function is an example. While technically called via "window.alert," we typically just write "alert" by itself, as shown under Getting Started Testing above. Other areas have their own object name, like screen. Ironically, "browser" is not an object name! You can learn more about the Browser Object Model on our separate page.
Before we leave this introduction, I would like to touch on the different versions of JavaScript. By versions, I essentially mean release levels which add new features. Why should you care? Because after a version is released, it may take an individual browser owner (Mozilla, Apple, Google...) years to fully implement the new features. Also, in reading about JavaScript, you will see abbreviated names for these versions, so you may wish to learn what they are.
JavaScript was written in 1995 by Brendan Eich. It was adopted as a "standard" by the ECMA (European Computer Manufacturers Association) in 1997 and given the official language name, ECMA Script 1, known as ES1. A bunch of significant changes were made in 2009 for ES5. ES6 added a lot of changes in 2015 and is now known as ECMA Script 2015, or sometimes ES6 Harmony. After that, releases were just known as ECMA Script yyyy, one each year from 2016 to 2020 (in June 2020), with ES terminology less common (although we are up to ES11 in 2020, which may also be referred to as ES2020).
The rule-of-thumb is that ES3 is supported by all browsers, and ES5 (2009!) is supported by all modern browsers. Internet Explorer (let's face it - it's dead, unsupported, and no one should be using it, but ...) does not support ES6 ECMA Script 2015 and beyond. The five major browsers do support ES6 2015 and can probably be trusted (my opinion...). In this tutorial I do not generally mention which version of JavaScript introduced support, though i do issue a few textual warnings about this. I wrote this section so when you see terms like ES6 elsewhere you will understand what they mean. When you lookup a JavaScript function on Mozilla, you will see statements like, "ES2015 provides arrow function expressions with even shorter syntax," and you will see a browser compatability chart at the bottom of each page. WikiPedia Entry on ECMAScript.
# # # # #
I offer these tutorials/reference documents or pages, recommended in this order:
AJAX | alert | appendChild | apply | arguments | arithmetic operators | Array.isArray | arrays | array properties and methods | array sorting | array functions | assertions | backtick character | bind | BOM | break | buttons | call | character classes | charAt | charCodeAt | class | class...extends | className | comments | comparing strings | concat | confirm | constructor | continuation of lines | continue | console | cookies | createElement | createRange / createContextualFragment | createTextNode | date methods | Date object | decodeURIComponent | do-while | document.write | DOM | endsWith | exclude | falsy value | for | forEach arrays | forEach objects | for...in array | for...in object | function borrowing | functions | get and set | getElementById | getElementByTagName | global search | global variable | hexadecimal notation | href | if-then-else | include/exclude | includes | indexOf | iterate | innerHTML | insertAdjacentHTML | JavaScript versions | join | lastIndexOf | leave | local variable | localeCompare | logic operators | match | Math object | metacharacters | methods | move | navigator.userAgent | new line | nodes | objects | Object.assign | Object.create | Object.entries | Object.keys | Object.values | onclick | outerHTML | parsing | prefix/postfix notation | promises | prompt | properties | push and pop | quantifiers | querySelector | regular expressions | remove | repeat | replace | reserved words | reverse | rounding | scope | screen | search | shift and unshift | slice array | slice string | split | sorting arrays | sorting objects | splice | split | StartsWith | strings | style modification | substr | substring | tagName | template literals | ternary operator | test | testing | textContent | this | toFixed | toLocalString (for dates) | toString | toUpperCase | toLowerCase | trim | truthy value | typeof | url | variables | while | window | window.open/close | XMLHttpRequest (XHR)
As a point of information, this Index is hard-coded in the Intro document and picked up dynamically and inserted in each tutorial via a JavaScript routine. This allows me to make updates in only one place and have them be dynamically loaded wherever needed.
Let me know if this tutorial/reference document was useful, and send in any comments or corrections.
Fred