Académique Documents
Professionnel Documents
Culture Documents
| HOME
Table of Contents (Hide)
1. Introduction
2. JavaScript by Examples
2.1 Example 1: Functions alert() and document.write()
2.2 Example 2: Variables and Functions prompt(), confirm()
2.3 Example 3: The Date Object
2.4 Example 4: Loops
2.5 Example 5: User-defined Functions and onclick Event Handler
2.6 Example 6: More Event Handlers: onload, onmouseover and onmouseout
2.7 Example 7: Separating HTML, CSS and JavaScript
2.8 Example 8: Manipulating the Contents of HTML Elements
2.9 Example 9: Intercepting a Hyperlink
2.10 More Advanced JavaScript Examples
2.11 Debugging JavaScripts
2.12 JavaScript IDE
3. JavaScript and HTML
3.1 The <script> Element
3.2 In <head> or <body>?
3.3 External JavaScripts
3.4 The <noscript> Element
4. JavaScript Basic Syntax
4.1 Comments
4.2 Expression
4.3 Statement and Block
4.4 Variable, Literals & Types
4.5 The number Type, Literals & Operations
4.6 The string Type, Literals & Operations
4.7 The boolean Type, Literals & Operations
4.8 Explicit Type Conversion
4.9 Flow Control - Decision
4.10 Flow Control - Loops
4.11 Arrays
4.12 Associative Array
4.13 Functions
4.14 Scope of a Variable: Global vs. Function-Local
4.15 Interacting with Users
4.16 Other Top-level Built-in Functions
4.17 An Introduction to Events
5. Objects
5.1 Objects are Everywhere!
5.2 Properties and Methods
5.3 Creating Objects via Object Initializer
JavaScript
Basics
1. Introduction
JavaScript is the most widely used client-side programming language that lets you supercharge
your HTML with interactivity, animation and dynamic visual effect for better User Interface and
User Experience (UI/UX). It is:
a client-side scripting language to enrich web user-interfaces and create dynamic web
pages (e.g., form input validation, and immediate response to user's actions).
the engine that supports AJAX (Asynchronous JavaScript and XML), which generate
renew interest in JavaScript.
JavaScript works together with HTML/CSS. HTML provides the contents (or structure); CSS
specifies the presentation; and JavaScript programs the behavior. Together, they enrich the
UI/UX of the web users.
History and Versions
JavaScript, originally called LiveScript, was created by Brendan Eich at Netscape in 1995. Soon
after, Microsoft launched its own version of JavaScript called JScript. Subsequently, Netscape
submitted it to ECMA (formerly "European Computer Manufacturers Association", now "Ecma
International - European association for standardizing information and communication
systems") for standardization, together with Microsoft's JScript.
The ECMA Specification is called "ECMA-262 ECMAScript Language Specification" (also
approved as "ISO/IEC 16262"):
1.0 (1996)
1.6, 1.7:
Remember that JavaScript is a client-side program that you downloaded from a server, and run
inside the browser of your (client) machine. What to stop someone from writing a JavaScript that
wipes out your hard disk, or triggers a denial-of-service attack to another server? As a result, for
security purpose,
1. It cannot read file from the client's machine.
2. It can only connect to the server that it come from. It can read file from the server that it
come from. It cannot write file into the server machine.
3. It cannot connect to another server.
4. It cannot close a window that it does not open.
JavaScript is Now Everywhere!
JavaScript was originally created as a client-side web programming language, running in a web
browser, to supercharge HTML. It has grown beyond the client-side programming.
The popular Node.js is a standalone JavaScript engine that lets you run JavaScripts in a
standalone manner (i.e., without a browser). Node.js also enables you to write server-side
programs in JavaScript, i.e., you can now write both your client-side programs and server-side
programs in the same language. Many front-end web development tools, such as Gulp.js and
Bower, are built upon Node.js and programmed in JavaScript.
JavaScript is also used for writing scripts for Software such as Acrobat, Dreamweaver and
Google Apps.
jQuery
jQuery is a cross-browser JavaScript Library. It is reported that more than 64% of the production
websites are written in jQuery nowadays (as in May 2015). jQuery is JavaScript (but having its
own extension syntax), hence, you need to understand JavaScript. I suggest you read through the
JavaScript syntax (and pay particular attention to objects), and then switch into jQuery for your
production. Read "jQuery Basics".
2. JavaScript by Examples
I shall assume that you know HTML and CSS (read my HTML/CSS articles otherwise). I shall
also assume that you understanding some programming basics such as variables, if-else and forloop constructs.
You need a text editor to write your JavaScript. You could use a plain text editor such as
NotePad. But to improve your productivity, a good programming text editor is essential. There
are many freeware/shareware available, such as Sublime Text (@ http://www.sublimetext.com/),
NotePad++ (http://notepad-plus.sourceforge.net), PSPad (www.pspad.com), TextPad
(www.textpad.com). You can also use a full-scale IDE such as NetBeans or Eclipse, which
provides content-assist (auto-complete) feature that greatly enhances your productivity.
JavaScripts run inside a browser. There are standards on JavaScript. But the Big-5 (Chrome,
Firefox, IE, Safari and Opera), in particular the IE, does not adhere to all the standards strictly.
Furthermore, they create their own extensions. Hence, the behavior of JavaScript could be
different in different browsers. You may need to test your JavaScripts on more than one
browsers. [That's where jQuery comes in handy, as jQuery provides cross-browser support.]
2.1 Example 1: Functions alert() and document.write()
Let us write our first JavaScript to print the message "Hello, world".
Start with a new file and enter the following codes. Do not enter the line numbers, which is used
to aid in explanation. Take note that:
"Extra" white spaces (blanks, tabs and newlines) are ignored. That is, multiple white
spaces is treated as a single blank character. You could use them liberally to make your
program easier to read.
Save the file as "JSExAlertWrite.html" (or any filename that you prefer, with file extension of
".html" or ".htm"). Run the script by loading the HTML file into a JavaScript-enabled browser
(e.g., One of the BIG FIVE - Chrome, Firefox, Internet Explorer, Safari or Opera).
JSExAlertWrite.html
<!DOCTYPE html>
<!-- JSExAlertWrite.html -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Example: Functions alert() and
document.write()</title>
<script>
alert("Hello, world!");
</script>
</head>
<body>
<h1>My first JavaScript says:</h1>
<script>
document.write("<h2><em>Hello world, again!
</em></h2>");
document.write("<p>This document was last modified on
"
+ document.lastModified + ".</p>");
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
How it Works?
1. JavaScripts are programming codes that are embedded inside an HTML document. The
codes are contained between a pair of <script> and </script> tags, as follows:
2. <script>
3.
// Your JavaScript programming codes here!
</script>
11. The alert() and document.write() are some of the commonly-used built-in functions
provided in JavaScript.
TRY: Print the document's title and the URL location. (Hints: use document.title and
document.location properties.)
Don't Get Caught by the Cache - Do Control-Refresh (or Control-F5)
If you modify the codes and reload the web page, the new codes may not get executed because
the browser caches the previously loaded version. You could use Control-F5 (Control-Refresh) to
ask the browser to discard the cache, and fetch a new page.
2.2 Example 2: Variables and Functions prompt(), confirm()
This script prompts the user for his/her name, confirms the name, and prints a greeting message.
There are three kinds of pop-up dialog boxes for interacting with the users:
1. The alert(aString) function puts the aString on a pop-up box with a OK button. User
needs to click the OK button to continue.
2. The prompt(promptingString, defaultInputString?) function puts up an input pop-up
box with the promptingString with an OK and Cancel buttons. It returns the input
entered by the user as a string; or a special value called null if the user hits the Cancel
button. The optional parameter defaultString specifies the initial string to be shown. In
this article, I shall indicate optional function parameters with a trailing '?' for
compactness.
3. The confirm(aString) function puts aString on a pop-up box with OK and Cancel
buttons. It returns true if user hits the OK button; or false otherwise.
JSExVar.html
<!DOCTYPE html>
<!-- JSExVar.html -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Example: Variables and functions prompt()
and confirm()</title>
<script>
var username = prompt("Enter your name: ", "");
if (confirm("Your name is " + username)) {
document.write("<h1>Hello, " + username + "!</h1>");
} else {
document.write("<h1>Hello, world!</h1>");
}
</script>
</head>
<body>
<p>Welcome to JavaScript!</p>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
How it Works?
1. Line 8 declares a variable called username, via the keyword var. A variable is a named
storage location that holds a value. Once the variable is declared, you can assign (and reassign) a value to that variable, via the assignment operator '=' (Line 9).
2. Line 9 invokes the prompt(promptingString, defaultString?) function to pop out a
dialog box, and reads in the string entered by the user. The string read is assigned to the
variable username. The function prompt() is similar to the alert(), but it accepts a
user's input.
3. In Line 10, the confirm(aString) function puts up the message and returns either true
or false, depending on whether the user hits the OK or Cancel button.
4. If the result is true, Line 11 prints "Hello, username!". Otherwise, Line 13 prints
"Hello, world!".
TRY: Instead of printing the greeting message using document.write(), do it via an alert().
2.3 Example 3: The Date Object
The following script creates a Date object representing the current date-time, and prints the
current time.
JSExDate.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<!-- JSExDate.html -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Example: The Date object</title>
<script>
var now = new Date();
// current date/time
var hrs = now.getHours();
// 0 to 23
var mins = now.getMinutes();
var secs = now.getSeconds();
document.writeln("<p>It is " + now + "</p>");
document.writeln("<p>Hour is " + hrs + "</p>");
document.writeln("<p>Minute is " + mins + "</p>");
document.writeln("<p>Second is " + secs + "</p>");
if (hrs < 12) {
document.writeln("<h2>Good Morning!</h2>");
} else {
document.writeln("<h2>Good Afternoon!</h2>");
}
</script>
</head>
<body></body>
</html>
How it Works?
Line 8 declares a variable called now. It also creates a Date object (via the new operator),
which contains the current date-time stamp, and assign it to now.
"//" begins an end-of-line comment (Lines 8 and 9). Comments are ignored by the
JavaScript engine but important in explaining your codes to others (and to yourself three
days later).
Line 9 declares a variable called hrs. It also invokes the function getHours() on object
now, in the form of now.getHours(), to retrieve the hour part of object now, and assign it
to variable hrs. Lines 9 and 10, similarly, handle the minutes and seconds.
Lines 16-20 contains a conditional if-then-else statement. Depending on the value of hrs,
one of the messages will be displayed.
TRY:
1. Modify the above script to print the current date, month, year and day of the week.
(Hints: Use functions getDate(), getMonth(), getFullYear() and getDay() of a Date
object. getDate() returns 1-31. getMonth() returns 0 to 11 for January to December.
getFullYear() returns a 4-digit year. getDay() returns 0 to 6 for Sunday to Saturday).
2. Use a conditional statement to print the day of the week in word (i.e., 0 for Sunday, 1 for
Monday and etc.). (Hints: Use the if-elseif-elseif...else construct as follow.)
3. if ( condition-1 ) {
4.
block-1 ;
5. } else if ( condition-2 ) {
6.
block-2 ;
7. } else if ( condition-3 ) {
8.
block-3 ;
9. ......
10. ......
11. } else {
12.
block-n ;
}
<!DOCTYPE html>
<!-- JSExLoop.html -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Example: Loop</title>
</head>
<body>
JSExLoop.html
9
10
11
12
13
14
15
16
17
<h2>Testing Loop</h2>
<script>
var multiplier = prompt("Enter a multiplier: ");
for (var number = 1; number <= 100; number++) {
document.writeln(number * multiplier);
}
</script>
</body>
</html>
How it Works?
Line 11 prompts the user for a number, and assigns it to the variable multiplier.
There are four parts in a for-loop. Three of them, initialization, test and post-processing,
are enclosed in brackets () and separated by 2 semicolons. The body contains the
repetitive task to be performed. The initialization statement is first executed. The test is
then evaluated. If the test returns true, the body is executed; followed by the postprocessing statement. The test is evaluated again and the process repeats until the test
returns false. When the test is false, the for-loop completes and program execution
continues to the next statement after the for-loop. The following flow chart illustrates the
for-loop process:
In this example, the variable number is initialized to 1. If number is less than or equal to
100, the body of the loop executes, followed by the post-processing statement, which
increment the value of number by 1. The loop repeats until the value of number is NOT
less than or equal to 100 (i.e., more than 100).
TRY:
1. Modify the above script to prompt the user for the multiplier as well as the number of
multiples to be printed (in two prompt() statements).
2. Modify the above script to print only multiples that are odd number. (Hint: The modulo
operator "%" can be used to compute the remainder, e.g., x % 2 computes the remainder
of x divides by 2, which results in either 0 or 1.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
How it Works?
Lines 8-10 define a function called openNewWindow(), via the keyword function. The
function invokes the built-in function open(url), which opens a new browser window (or
tab) and loads the page "JSEx1.html".
Lines 15-16 create an HTML button. Clicking the button triggers the onclick event
handler, i.e., openNewWindow() defined earlier.
onload:
onmouseover
and onmouseout: fires when the user points the mouse pointer at/away
from the HTML element.
JSExMoreEvents.html
<!DOCTYPE html>
<!-- JSExMoreEvents.html -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Example: Events onload, onmouseover
and onmouseout</title>
<script>
var msgLoad = "Hello!";
</script>
</head>
<body onload="alert(msgLoad)">
<p>"Hello" alert Box appears <em>after</em> the page is
loaded.</p>
<p onmouseover="this.style.color='red'"
onmouseout="this.style.color=''">Point your mouse
pointer here!!!</p>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Line 8 defines a variable msgLoad, which holds the strings to be displayed in the onload
event handlers.
In the <body> opening tag (Line 12), we define the onload event handler for the load
event. It invokes alert() with the message defined earlier.
Line 13 and 14 defines the event handlers onmouseover and onmouseout for the HTML
element <p>. The text's color will be changed to red when the user points the mouse
pointer at the element (by setting the CSS style property color to red), and revert back to
its original color when the mouse pointer is moved away (by resetting the CSS style
property color to an empty string). The special keyword this refer to this object.
JSExFiles.html
<!DOCTYPE html>
<!-- JSExFiles.html -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Example: Separating HTML, CSS and
JavaScript</title>
<link rel="stylesheet" href="JSExFiles.css">
<script src="JSExFiles.js"></script>
</head>
<body>
<p>"Hello" alert Box appears <em>after</em> the page is
loaded.</p>
<p id="magic">Point your mouse pointer here!!!</p>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
JSExFiles.css
1
2
3
4
5
6
/* JSExFiles.css */
@CHARSET "UTF-8";
.highlight {
color: red;
}
JSExFiles.js
// JSExFiles.js
window.onload = function() {
init();
alert("Hello!");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function init() {
document.getElementById("magic").onmouseover = function() {
this.className = "highlight";
}
document.getElementById("magic").onmouseout = function() {
this.className = "";
}
}
How it Works?
1. Placing the scripting codes inside the HTML page is not a good software engineering
practice. Instead, the now-preferred approach is to place the scripts, as well as CSS styles,
in external files, which can then uniformly applied to all pages in your website.
2. Let's begin with the HTML file. Now, the HTML file keeps only the contents, no
presentation style and nor programming logic.
You can select HTML element(s) within the current page via these functions:
1. document.getElementById(anId): returns the HTML element with id="anId", or null if
the id does not exist. The id attribute should be unique within an HTML document.
2. document.getElementsByTagName(aTagName): returns an array of HTML elements with
the given HTML tag name.
3. document.getElementsByClassName(aClassName): returns an array of HTML elements
having attribute class="aClassName".
4. document.getElementsByName(aName): returns an array of HTML elements having
attribute name="aName".
To modify the content of an HTML element, you can assign a new value to the innerHTML
property of that element. (The property innerHTML is really useful and is supported in most of
the browsers. It is, however, not included in the W3C DOM specification?!)
JSExInnerHtml.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<!-- JSExInnerHtml.html -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Example: Modifying the Content of HTML
Elements</title>
<script src="JSExInnerHtml.js" ></script>
</head>
<body>
<h1 id="heading1">Heading 1</h1>
<h2>Heading 2</h2>
<h2>Heading 2</h2>
<p class="para">Paragraph 1</p>
<p class="para">Paragraph 2</p>
<p class="para">Paragraph 3</p>
<input type="button" id="btn1" value="Change Heading
1" />
<input type="button" id="btn2" value="Change Heading
2" />
<input type="button" id="btn3" value="Change
Paragraph" />
</body>
</html>
JSExInnerHtml.js
1
2
3
4
5
// JSExInnerHtml.js
window.onload = init;
function init() {
document.getElementById("btn1").onclick = changeHeading1;
JSExInnerHtml.js
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
document.getElementById("btn2").onclick = changeHeading2;
document.getElementById("btn3").onclick = changeParagraph;
function changeHeading1() {
var elm = document.getElementById("heading1");
element
elm.innerHTML = "Hello";
}
function changeHeading2() {
var elms = document.getElementsByTagName("h2");
of elements
for (var i = 0; i < elms.length; i++) {
elms[i].innerHTML = "Hello again!";
}
}
// One
// Array
function changeParagraph() {
var elms = document.getElementsByClassName("para");
Array of elements
for (var i = 0; i < elms.length; i++) {
elms[i].innerHTML = "Hello again and again!";
}
}
//
How it works?
1. This HTML document contains a <h1> element with an unique id="heading1" (Line
10), two <h2> elements (Line 11-12), three <p> elements with class="para" (Line 1315), and three <input type="button"> with unique id (Line 16-18).
2. In the user-defined function changeHeading1(), we use
document.getElementById("heading1") to select the <h1> element, and then modify
its innerHTML property.
3. In changeHeading2() function, we use document.getElementsByTagName("h2") to
select all the <h2> elements in an array elms. We then use a for-loop to iterate through all
the elements in the array. The elms.length property keeps the length of the array.
4. In changeParagraph() function, we use
document.getElementsByClassName("para")
5. The page contains three buttons to trigger the functions defined (Line 16-18).
6. The script contains a function init(), which is assigned as the onload handler via
window.onload=init. That is, init() will be triggered after the page is loaded. The
selected via
TRY: [TODO]
2.9 Example 9: Intercepting a Hyperlink
This example uses a script to intercept a hyperlink to put up a warning message, then proceed to
the link.
JSExLink.html
<!DOCTYPE html>
<!-- JSExLink.html -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Example: Intercept an Hyperlink</title>
<script src="JSExLink.js" ></script>
</head>
<body>
<a href="JSExAlertWrite.html" id="myLink">JavaScript Example
1</a>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
JSExLink.js
// JSExLink.js
window.onload = init;
1
2
3
4
5
6
7
8
9
10
function init() {
document.getElementById("myLink").onclick = showWarning;
}
function showWarning() {
return confirm("Warning! Proceed with care!");
}
How it works?
In Chrome and Firefox, you can press F12 to activate the developer Tools (hence called F12
Developer Tools).
Firefox: Firebug plug-in (or Web Developer Tools) - ESSENTIAL!!!
Simply GREAT and MUST HAVE for debugging HTML/CSS and JavaScript!!! You can install
firebug from http://getfirebug.com/. It provides these features:
1. Console: View the JavaScript error messages. Start the firebug and switch to the
"Console" panel.
2. Script: View and debug JavaScript. Start the firebug. Switch to the "Script" panel.
"Enable" or "Reload" if necessary. You can set a breakpoint by clicking on the statement
number, single step through the JavaScript statements, watch the expression, and etc.
Read "JavaScript Debugger and Profiler".
3. DOM: View the HTML DOM of the current document.
4. HTML and CSS.
To debug JavaScript under Firebug:
1. Launch Firebug Choose the "Script" panel to view your JavaScript, shown with greenbold line numbers.
2. Refresh (Ctrl-F5) the page, and check the error console (Under "Console" "Errors")
for syntax errors! Correct all the syntax errors.
3. To trace the program, set breakpoints at selected JavaScript statements, by clicking on the
right margin (to the left of line number). A red circle shows up denoting a breakpoint.
Take note that you can only set breakpoint on statements with a green-bold line number.
[If your JavaScript statements do not have a green-bold line number, there are syntax
errors on these statements. You need to correct the syntax errors and reload the page.]
4. Trigger the script (via clicking button/link, or reloading the page). The execution stops at
the first breakpoint. You can then step-over the statement (or step-into function), and
inspect the variables by positioning the mouse pointer on the variable; or add the variable
to "watch".
5. You can resume the execution (via the continue button).
Notes: If you get the error "Script Panel was inactive during page load" when switching into the
"script" panel, you need to disable "private browsing" in Firefox's Tools Options Privacy.
Firefox also has a built-in "Web Developer Tools", having similar functions as Firebug plug-in.
Chrome: Developer Tools
You can activate Chrome's Developer Tools via "Control" "More Tools" "Developer Tools".
The console.log()
Instead of using alert() and document.write() to show the intermediate results, you can also
use console.log(message[, element]), which writes the message and the value of the element
to the error console. It does not interfere the appearance you web page nor your normal
operations.
For example, modify the JavaScript in Example 8 to print the values of innerHTML before
modification. You need to turn on the console (press F12) to see the output.
JSExInnerHtmlDebug.js
1
2
3
4
5
6
7
8
9
10
11
// JSExInnerHtmlDebug.js
window.onload = init;
function init() {
document.getElementById("btn1").onclick =
changeHeading1;
document.getElementById("btn2").onclick =
changeHeading2;
document.getElementById("btn3").onclick =
changeParagraph;
}
JSExInnerHtmlDebug.js
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function changeHeading1() {
var elm = document.getElementById("heading1"); //
One element
console.log(elm.innerHTML); // Print current value
before modification
elm.innerHTML = "Hello";
}
function changeHeading2() {
var elms = document.getElementsByTagName("h2");
Array of elements
for (var i = 0; i < elms.length; i++) {
console.log(elms[i].innerHTML);
elms[i].innerHTML = "Hello again!";
}
}
//
function changeParagraph() {
var elms =
document.getElementsByClassName("para"); // Array of
elements
for (var i = 0; i < elms.length; i++) {
console.log(elms[i].innerHTML);
elms[i].innerHTML = "Hello again and again!";
}
}
You can write JavaScripts by creating a web application under NetBeans (Read "Developing web
application under NetBeans"), via "new" "Others" In "Categories", select "Other" In
"File Types", select "HTML File" or "JavaScript File". NetBeans provides content-assist (or
auto-complete) feature, which greatly improves your productivity.
You need to use Firebug or Web developer Tools to debug JavaScript.
Eclipse
[TODO]
Aptana Studio
An open source IDE (based on Eclipse), which supports JavaScript and Ajax.
src="JavaScriptFilename.js"></script>
Take note that the closing tag </script> is needed although there is no content!?
In HTML4/XHTML1.0, you need to include type="text/javascript" in the <script>
opening tag.
3.4 The <noscript> Element
The <noscript>...</noscript> element provide an alternate message if scripting is disabled
or not supported.
4.2 Expression
An expression is a combination of variables, literals, operators, and sub-expressions that can be
evaluated to produce a single value.
4.3 Statement and Block
A statement is a single instruction consisting of operators, variables and expression. It is strongly
recommended to end each statement with a semicolon ';' (Although it is not strictly necessary
as the new-line can also serve as the statement terminator in JavaScript).
A block consists of zero or more statements enclosed in a pair of curly braces { statements }.
No semicolon is needed after the closing brace.
4.4 Variable, Literals & Types
Variables & Assignment Operator '='
A variable is a named storage location that holds a value, e.g., sum, average, name and message.
A variable name (aka identifier) must begins with a letter (a-z, A-Z), underscore '_', or
dollar sign '$'. Subsequent characters could contain digits (0-9). Take that that jQuery
uses $, $(), which are valid identifiers. Hyphen '-' and space are not allowed, hence,
font-size, roman new, are NOT valid identifiers.
You can assign (and re-assign) a value to a variable using the assignment '=' operator.
Literals
A literal is a fixed value, e.g., 5566, 3.14, "Hello", true, that can be assigned to a variable, or
form part of an expression.
Types
Script, Perl, Python). You do not have to explicitly declare the type of a variable (such as int and
float) during declaration. The type is decided when a value is assigned to that variable. If a
number is assigned, the variable takes on the number type and can perform numeric operations
such as addition and subtraction. If a string is assigned, the variable takes on the string type and
can perform string operations such as string concatenation.
Operator typeof
You can use the operator typeof to check the type of a variable.
The undefined Type and undefined Literal Value
An undeclared variable (via var keyword) takes on a special type called undefined. You cannot
refer to its value.
When a variable is declared (via var keyword) without assigning an initial value, it takes on the
type undefined and holds a special value called undefined (uninitialized is probably more
precise?!), As soon as a value is assigned, the variable takes on the type of that value. The act of
putting a value into a variable sets its type. You can change the type of a variable by re-assigning
a value of another type. Types are converted automatically as needed during execution (known as
dynamically-typed).
For examples,
// Undeclared variable v1
console.log('type:' + typeof v1);
//console.log('value:' + v1);
// type: undefined
// value: error: v1 is not defined
// type: string
// value: abc
// type: string
// value: 123
// type: number
// value: 123
// type: number
// value: 55.66
// type: number
// value: 123
/* objects */
// null object
v1 = null;
console.log('type: ' + typeof v1);
console.log('value: ' + v1);
// type: object
// value: null
// object
v1 = {name:'peter', age:21};
console.log('type: ' + typeof v1);
console.log('value: ' + v1);
console.log('value: ' + v1.name);
console.log('value: ' + v1.age);
//
//
//
//
// Date object
v1 = new Date();
console.log('type: ' + typeof v1);
console.log('value: ' + v1);
GMT+0800 (SGT)
type: object
value: [object Object]
value: peter
value: 21
// type: object
// value: Tue May 26 2015 00:35:12
// Function object
v1 = function() { return 'hello'; };
console.log('type: ' + typeof v1); // type: function
console.log('value: ' + v1);
// value: function () { return 'hello'; }
Constants
You can create a read-only, named constant with the keyword const (in place of var). For
example,
const SIZE = 9;
Unfortunately, the keyword const has yet to be widely supported by web browsers. So don't use.
4.5 The number Type, Literals & Operations
A variable of type number holds a number, either an integer or a floating-point number.
Integer literals can be expressed in:
Binary: begins with 0b (or 0B), e.g., 0b10011100 or -0B11001100. [Binary may not be
supported in some browsers.]
Floating-point literals can be expressed in the usual form (e.g., 3.1416) or scientific notation,
e.g., -1.23e4, 4.56E-7.
JavaScript also provides some special number literals:
Arithmetic Operations
Arithmetic operations, as tabulated below, can be applied to numbers. The following results are
obtained assuming that x=5, y=2 before the operation.
Operator
Description
+
Addition
Subtraction (or Unary
Negation)
*
Multiplication
/
Division
Modulus (Division
%
Remainder)
++
--
Result
z is 7
z = x - y;
z is 3
z = x * y;
z = x / y;
z is 10
z is 2.5
z = x % y;
z is 1
y = x++; z = ++x;
Same as: y = x; x = x+1; x
= x+1; z = x;
y = --x; z = x--;
Same as: x = x-1; y = x; z
= x; x = x-1;
y is 5; z is 7;
x is 7
y is 4; z is 4;
x is 3
Description
Addition cum Assignment
Subtraction cum Assignment
Multiplication cum Assignment
Division cum Assignment
Modulus cum Assignment
Example
Result
x += y; Same as: x = x + y;
x -= y;
Same as: x = x - y;
x *= y; Same as: x = x * y;
x /= y;
Same as: x = x / y;
x %= y; Same as: x = x % y;
parseInt(aString): Parse the aString until the first non-digit, and return the number; or
NaN.
parseFloat(aString):
console.log(isNaN('123'));
console.log(isNaN('1.23'));
console.log(isNaN('123abc'));
// false
// false
// true
It is interesting to note that JavaScript does not have counterpart functions like
isNumber(), isNumeric().
Number(aString): Return the number represented by aString, or NaN. Take that that this
function name begins with uppercase, because this is a type casting operation.
var n = 1.2345;
console.log(n.toFixed(2));
console.log(n);
// 1.23
// 1.2345 - No change!
Unlike Java/C/C++, but like HTML/CSS's attributes, you can use either single quotes or double
quotes for string. This is handy as you can use single quotes if the string contains double
quotes (e.g., '<div id="header"></div>'), without using the escape sequences (e.g., "<div
id=\"header\"></div>").
JavaScript is dynamically-type, and performs type conversion automatically. When a string
value is used in arithmetic operations (such as subtraction or multiplication), JavaScript runtime
automatically converts the string to a number if it represents a valid number; or a special
number called NaN (not-a-number) otherwise. For example,
// In arithmetic operations, a
console.log('55' - '66');
//
console.log('55' * 2);
//
console.log('Hello' - 1);
//
If both the operands to a '+' operator are numbers, it performs the usual numeric addition.
However, if one (or both) of the operand is a string, the '+' operator is overloaded to perform
string concatenation. The other operand will be converted to a string, if necessary. For
example,
// '+' operator is overloaded to perform string concatenation if one of the
operands is a string
console.log(11 + 22);
// gives Number 33 (usual addition)
console.log('11' + '22');
// gives string 1122 (concatenation)
console.log('11' + 22);
// gives string 1122 (concatenation)
console.log('Hello' + 22); // gives string Hello22 (concatenation)
Built-in Functions parseInt(), parseFloat() and Number()
To convert a numeric string to a number, you could use the built-in functions parseInt() or
parseFloat(), which returns a number if conversion is successful; or NaN otherwise. For
example,
var magic = "11";
// string
console.log(magic + 22);
console.log(parseInt(magic) +
console.log(parseInt(magic) +
console.log(parseInt(magic) +
33.33
console.log(parseInt("abc"));
Take note that parseInt() works as long as the string begins with digits. It will parse up to the
first non-digit. For example,
console.log(parseInt("10px"));
// Return number 10
You can also use the function Number(), which converts the object argument to a number that
represents the object's value; or NaN if conversion fails. For example,
var magic = "8888"
console.log(magic + 8);
// string concatenation
console.log(Number(magic) + 8); // addition
// Number() also works on Object such as Date, e.g.,
console.log(new Date(2015, 5, 1, 12, 34, 56));
String's Properties
String's Operations
.charAt(index): returns the character at the index position. Index begins from 0. Negative
index can be used, which counts from the end of the string.
Multi-line String
You can create a multi-line string via back-quotes `...`. For example,
console.log(`string line 1
string line 2`);
// Same as
console.log('string line 1\nstring line 2');
The following relational operators, which produce a boolean result, are defined in JavaScript.
The results are obtained assuming num=8, str='8'.
Operator
Description
Example (num=8,
Result
str='8')
num == 8
str == '8'
num == str
8 == '8'
true
true
true
true
num === 8
true
true
false
false
==
Equal To
(in Value)
!=
Not Equal To
===
!==
>
Greater Than
Greater Than or
Equal To
Less Than
Less Than or Equal
To
>=
<
<=
=== vs. ==
The strictly equality operator === returns true if both operands have the same type and same
value; while == returns true if both operands have the same value, but may or may not be the
same type.
JavaScript needs to provide two different equality operators, because it is loosely type and carries
out automatic type conversion in many situation. For example,
When a number is compared with a string, the string is converted to a number (or NaN if it
does not contain a valid number). Hence, (8 == "8") returns true. But, (8 === "8")
returns false, because the operands are not of the same type.
===, !==, ==, != can be applied to boolean (and all the JavaScript types), e.g., ("" ==
false) gives true (because empty string is converted to false); but ("" === false)
gives true.
It is RECOMMENED to use === (or !==), instead of == (or !=), unless you are certain
that type is not important.
When two strings are compared, the encoding order (ASCII or Unicode table) is used. Hence,
string "8" is greater than string "10".
For example,
// Comparing numbers
var x = 8;
console.log(x == 8);
console.log(x == '8');
console.log(x === 8);
console.log(x === '8');
//
//
//
//
//
// true
// true (string converted to number)
type:number, value:8
true (same value)
true (string converted to number)
true (same type and value)
false (different type)
Logical Operators
Description
Logical AND
Logical OR
Logical NOT
Example
Result
Evaluation of logical operations are always short-circuited. That is, the operation is terminated as
soon as the result is certain, e.g., (false && ...) is short-circuited to give false, (true
|| ...) gives true, the ... will not be evaluated.
4.8 Explicit Type Conversion
The JavaScript runtime performs type conversion automatically. However, at times, you may
need to convert from one type to another explicitly.
Converting a number to a string: Simply concatenate the number with an empty string, e.g.,
"" + 5 gives "5".
Converting a string to a number: Use built-in functions parseInt(string),
parseFloat(string) or Number(string) to convert a string which contains a valid number. For
example, parseInt("55") gives 55, parseInt(55.66) gives 55, parseInt("55.66") gives 55,
parseFloat("55.66") gives 55.66, parseInt("55px") gives 55, but parseInt("Hello")
gives NaN.
Converting a float to an integer: Use parseInt() (e.g., parseInt(55.66) gives 55), or built-in
mathematical functions such as Math.round(), Math.ceil() or Math.floor().
4.9 Flow Control - Decision
JavaScript provides these flow control construct. The syntax is the same as Java/C/C++.
Syntax
if (condition) {
trueBlock;
}
if (condition) {
trueBlock;
} else {
falseBlock;
}
variable = (condition) ? trueValue :
falseValue;
Example
if (day === 'sat' || day === 'sun') {
alert('Super weekend!');
}
if (day === 'sat' || day === 'sun') {
alert('Super weekend!');
} else {
alert('It is a weekday...');
}
var max = (a > b) ? a : b;
var abs = (a >= 0) ? a : -a;
Same as
if (condition) { variable =
trueValue; }
else { variable = falseValue; }
if (condition1) {
block1;
} elseif (condition2) {
block2;
} elseif (...) {
......
} else {
elseBlock;
}
switch (expression) {
case value1:
statements; break;
case value2:
statements; break;
......
......
default:
statements;
}
Example
// Sum from 1 to 100
var sum = 0, number = 1;
while (number <= 100) {
sum += number;
}
// Sum from 1 to 100
var sum = 0; number = 1;
do {
sum += number;
}
// Sum from 1 to 100
var sum = 0;
for (var number = 1; number <= 100;
number++) {
sum += number;
}
continue - abort the current iteration, and continue to the next iteration.
label: - provide an identifier for a statement, which can be used by break label and
continue label.
Try to avoid these statements, as they are hard to trace and maintain.
4.11 Arrays
An array is an indexed collection. An array can be used to store a list of items (elements) under a
single name with an integral index. You can reference individual element via the integral index
in the form of anArrayName[anIndexNumber]. Furthermore, you can conveniently process all
the elements of an array collectively via a loop.
Creating an Array via Array Initializer
You can create an array by assigning an array literal to a variable, known as Array Initializer, in
the form of [value1, value2, ...]. For examples,
// Create an array by declaring a variable and assign an array literal
var weekdays = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
// You can print out an array
document.writeln(weekdays);
// sun,mon,tue,wed,thu,fri,sat
console.log(weekdays);
// ["sun", "mon", "tue", "wed", "thu", "fri",
"sat"]
// A JavaScript Array is actually an object
console.log(typeof weekdays);
// object
// You can get the length of the array via .length property
console.log(weekdays.length);
// 7
// A JavaScript array can contain mixed types (number, string, boolean)
var somethings = [1, 2.3, "abc", false];
console.log(somethings);
// [1, 2.3, "abc", false]
console.log(somethings.length); // 4
// A JavaScript array is dynamically allocated
var fruits = [];
// begins with an emtpy array
console.log(fruits);
// []
console.log(fruits.length); // 0
// Dynamically add an item
fruits[0] = "apple";
console.log(fruits);
console.log(fruits.length);
// ["apple"]
// 1
document.writeln(fruits);
console.log(fruits);
console.log(fruits.length);
// apple,,,orange
// ["apple", 3: "orange"]
// 4
Take note that JavaScript's array literal is enclosed in square bracket [...], instead of {...} in
Java/C/C++. JavaScript uses {...} for object literal (to be discussed later).
You can also use an Array Initializer to create an array with missing indexes. For example,
var fruits = ['apple', , , 'orange'];
console.log(fruits); // ["apple", 3: "orange"]
// fruits[1] and fruits[2] are undefined
Accessing an Item
You can access individual element of an array via an integral index, in the form of
anArrayName[anIndexNumber]. The index of the array begins at 0, and shall be a non-negative
integer.
Array's length
The length of the array is maintained in a variable called length, which can be accessed via
anArrayName.length. In fact, the property .length returns the last integral index plus 1, as
JavaScript's array index is 0-based. Nonetheless, you are allow to manipulate the .length. For
example,
a = ['11', '22', '33'];
console.log(a);
// ["11", "22", "33"]
console.log(a.length); // 3
a.length = 10;
console.log(a);
// ["11", "22", "33"]
console.log(a.length); // 10
Clearly, setting the .length does not affect the array elements.
Dynamic Array
Unlike Java/C/C++, the JavaScript array is dynamically allocated. You can add more elements to
an array. You can also remove the content of an element using keyword delete. For examples,
var days = ["sun", "mon", "tue"];
console.log(days.length); // 3
console.log(days);
// ["sun", "mon", "tue"]
// Dynamically add an item
days[5] = "fri";
console.log(days.length); // 6
console.log(days);
// ["sun", "mon", "tue", 5: "fri"] (items in
between are undefined)
// Remove an item. Set to undefined.
delete days[1];
console.log(days.length); // 6
console.log(days);
// ["sun", 2: "tue", 5: "fri"]
// Push an item at the end
days.push("sat");
console.log(days.length); // 7
console.log(days);
// ["sun", 2: "tue", 5: "fri", 6: "sat"]
// Remove the last item
console.log(days.pop());
console.log(days.length);
console.log(days);
// sat
// 6
// ["sun", 2: "tue", 5: "fri"]
console.log(days.shift()); // hi
console.log(days.length); // 6
console.log(days);
// ["sun", 2: "tue", 5: "fri"]
// Negative index?
days[-9] = 'hello';
console.log(days.length); // 6
console.log(days);
// ["sun", 2: "tue", 5: "fri", -9: "hello"]
// The index -9 is considered as an object property,
// outside the numerical indexes (to be discussed later)
Accessing All Items using for-loop with index
JavaScript provides a special for-index-in loop to process all the elements in an array. The
syntax is as follows, where index takes on the each of the index number of element which are not
undefined.
for (var index in arrayName) { ... }
For example,
var months = ["jan", "feb"]; // index 0 and 1
months[11] = "dec";
// indexes 2 to 10 undefined
for (var i in months) {
console.log(i + ": " + months[i]);
}
// 0: jan
// 1: feb
// 11: dec
The JavaScript's for-item-of loop
JavaScript provides a special for-item-of loop to process all the elements in an array. The
syntax is as follows, where item takes on the each of the element including the undefined.
for (var item of arrayName) { ... }
Add/Remove item(s)
You can:
Use push() to add one or more items to the end of an array. push() returns the resultant
length of the array.
Use unshift() to add one or more items to the beginning of an array. unshift() returns
the resultant length of the array.
For examples,
Purpose
Example
.length: the number of items including undefineds. In fact, .length is set to the last
index plus 1.
.join([separator]): join the elements of an array together into a single string, separated by
the separator (defaulted to ','). For example,
aString.split([separator, limit]): Reverse of join(). Take a string and split into an array
based on the separator. For example,
(3 items)
str = 'apple|*|orange|*|banana';
fruits = str.split();
console.log(fruits);
// ["apple|*|orange|*|banana"]
fruits = str.split('|*|');
console.log(fruits);
// ["apple", "orange", "banana"]
(one item)
(3 items)
fruits = str.split('*');
console.log(fruits);
// ["apple|", "|orange|", "|banana"]
(3 items)
.concat(value1, value2, ..., valueN): returns a new array composing of this array and the
given arrays or values. For example,
.reverse(): reverses the order of elements in the array, the first becomes last. For example,
console.log(a);
// ["10", "8", "a", "b"]
// Strings are sorted based on ASCII (Unicode) order.
// Hence, "10" is before "8", as '1' is before '8'
a = [8, 20, 5, 100];
a.sort();
console.log(a);
// [100, 20, 5, 8]
// numbers are also sorted based on ASCII (Unicode) order!!!
Take note take, by default, number are also sorted based on ASCII (Unicode) order. To
sort numbers numerically, you can supply a callback comparison function. The function
shall take 2 arguments, say a and b, and return a negative number if a < b; a positive
number if a > b; and 0 if a == b. For example,
var a = [8, 20, 5, 100];
a.sort( function(a, b) { return a - b; } );
console.log(a);
// [5, 8, 20, 100]
.push(): adds one or more elements to the end of an array and returns the resultant length
of the array.
.unshift(): adds one or more elements to the front of an array and returns the resultant
length of the array.
Arrays also support these iterative methods that iterate through each item of the array:
.forEach(callback): takes a function with an argument which iterates through all the items
in the array.
.map(callback): return a new array, which contains all the return value from executing
callback on each item. For example,
.filter(callback): return a new array, containing the items for which callback returned
true. For example,
.some(callback): return true if callback returns true for at least one item in the array.
For detailed specification and examples about a built-in object, check "Core JavaScript
References".
4.12 Associative Array
An associative array is an array of key-value pair. Instead of using numbers 0, 1, 2,... as keys as
in the regular array, you can use anything (such as string) as key in an associative array.
Associative arrays are used extensively in JavaScript and jQuery.
JavaScript does not support native associative array (it actually does not support native array
too). In JavaScript, associative arrays (and arrays) are implemented as objects (to be elaborate
later).
You can create an associative array via the Object Initializer. For example,
// Create an associative array of key-value pairs
var aStudent = {
name:
'peter', // string
id:
8888,
// number
isMarried: false
// boolean
};
// Add a new property via "index" operator, like an array
aStudent['age'] = 24;
// Use for..in loop to access all items
for (key in aStudent) {
name: peter
id: 8888
isMarried: false
age: 24
Take note that Array initializer uses square brackets [ ... ]; while object initializer (for
associative array) uses curly brackets { ... }.
4.13 Functions
Functions are useful:
A function accepts zero or more arguments from the caller, performs the operations defined in
the body, and returns zero or a single result to the caller.
The syntax for user-defined function is:
function functionName(argument1, argument2, ...) {
statements;
......
return aValue;
}
Functions are declared using the keyword function. You do not have to specify the return-type
and the types of the arguments because JavaScript is loosely typed. You can use a return
statement to return a single piece of result to the caller anywhere inside the function body. If no
return statement is used (or a return with no value), JavaScript returns undefined. Functions
are generally defined in the HEAD section, so that it is always loaded before being invoked.
To invoke a function:
functionName(argument1, argument2, ...)
Example:
<!DOCTYPE html>
<!-- "JSFunDemo.html" -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>Function Demo</title>
<script>
function add(item1, item2) {
// Take two numbers or strings
return Number(item1) + Number(item2); // Simply item1 + item2 concatenate
strings
}
</script>
</head>
<body>
<script>
var number1 = prompt('Enter the first integer:'); // returns a string
var number2 = prompt('Enter the second integer:'); // returns a string
alert('The sum is ' + add(number1, number2));
</script>
</body>
</html>
Function's arguments
Function has access to an additional variable called arguments inside its body, which is an array
containing all the arguments. For example,
<!DOCTYPE html>
<!-- "JSFunArguments.html" -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>Function Demo - Using the "arguments" variable</title>
<script>
function add() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += Number(arguments[i]);
}
return sum;
}
</script>
</head>
<body>
<script>
document.write(add(1, 2, 3, 4, 5) + "<br>");
document.write(add(1, 2) + "<br>");
document.write(add(1.1, "2.2") + "<br>");
</script>
</body>
</html>
Pass by Value vs. Pass by Reference
In JavaScript, primitive arguments are passed by value. That is, a copy of the variable is made
and passed into the function. On the other hand, objects are passed by references. That is, if you
modify the content of an object inside the function, the "copy" outside the function is also
affected.
Functions are objects in JavaScript (to be discussed later).
The Default Function Arguments
JavaScript lets you invoke a function omitting some trailing arguments. It sets the omitted
arguments to the value undefined. For example,
// Define a function with 3
function f1(a1, a2, a3) {
console.log('a1: type is
console.log('a2: type is
console.log('a3: type is
}
parameters
' + typeof a1 + ', value is ' + a1);
' + typeof a2 + ', value is ' + a2);
' + typeof a3 + ', value is ' + a3);
2);
a1: type is number, value is 1
a2: type is number, value is 2
a3: type is undefined, value is undefined
f1('hello', 1,
// a1: type
// a2: type
// a3: type
2);
is string, value is hello
is number, value is 1
is number, value is 2
You can use this feature to provide default value to function argument, for example,
// Define a function with default arguments
function f2(a1, a2, a3) {
// Set default for a2, if a2 is missing or null in function call
if (a2 === undefined || a2 === null) a2 = 88;
// Set default to a3
// a3 evaluates to false for undefined, null, '', 0, NaN, false
a3 = a3 || 'myDefault';
// more concise
console.log('a2: type is ' + typeof a2 + ', value is ' + a2);
console.log('a3: type is ' + typeof a3 + ', value is ' + a3);
}
// Invoke function with all the arguments
f2('hello', 1, 2);
// a2: type is number, value is 1
In the above example, we allow caller to omit the trailing arguments (a2, a3) or pass a null
value (which is a special literal for unallocated object).
The common idiom in practice today is to use the short-circuited OR expression (as in a3) to
provide default value if no value (undefined or null) is passed, provided the valid inputs cannot
be false, 0, '', and NaN that evaluate to false.
Anonymous (Inline) Functions
In JavaScript, you can define an anonymous function (without a function name) using the
following syntax:
function( parameters ) {
....
In JavaScript, a variable can hold a primitive (number, string, boolean). It can also hold a
function object. For example,
// Define a named function f1()
function f1(a1) {
return 'run f1()';
}
console.log(f1);
// function f1(a1)
console.log(f1('hello')); // run f1()
// Declare a variable f2 and assign it an anonymous function
// Same as above!
var f2 = function(a2) {
return 'run f2()';
}
console.log(f2);
// function f2(a2)
console.log(f2('hello'));
// f2(a2)
// Define a variable f3 and assign it a named function
var f3 = f1;
console.log(f3);
// function f1(a1)
console.log(f3('hello'));
// run f1()
As seen in the above example, there are two ways to define a function:
1. Use a function declaration statement in the form of:
function funcationName ( parameters ) { ...... }
Recall that a function takes zero or more arguments from the caller. In JavaScript, the argument
can be of any types: primitive, object or even function. That is, a function may take another
function as its argument.
For example, the following function take a function and an array as its arguments, and apply the
function to the array.
// Define a function, which takes a function and an array as its arguments,
// and apply the function to each item of the array.
function processArray (inFun, inArray) {
var resultArray = [];
for (var i in inArray) {
// apply function to each item of the inArray
resultArray[i] = inFun(inArray[i]);
}
return resultArray;
}
// Passing an anonymous function
// Square each item of an array
console.log(processArray( function(x) { return x*x; }, [1, 2, 3, 4, 5] ));
// [1, 4, 9, 16, 25]
// Cubic each item of an array
console.log(processArray( function(x) { return x*x*x; }, [1, 2, 3, 4, 5] ));
// [1, 8, 27, 64, 125]
// Passing a named function
function cube(x) { return x*x*x; }
console.log(processArray( cube, [1, 2, 3, 4, 5] ));
// [1, 8, 27, 64, 125]
Nested Function
var gvar = 8;
function sayHello() {
// local variable
var lvar = 'hello';
console.log(gvar); // can access global variable
console.log(lvar);
return lvar;
}
sayHello();
console.log(gvar); // can access global variable
//console.log(lvar); // error: lvar is not defined
// cannot access local variable outside the function
JavaScript does not have a block scope. A variable defined inside a block is either a local
variable to the enclosing function, or global. For example,
// global variable
for (var i = 0; i < 5; ++i) {
var msg = 'hello';
console.log(i);
}
console.log(i);
// 5 (i is global, not block-scope)
console.log(msg); // hello (msg is also global, not block-scope)
NOTE: ECMAScript 6 introduces the let variable declaration, which is block-scope. You use
the let keyword (instead of var) to define a variable. However, ECMAScript 6 is still
experimental and not widely supported.
4.15 Interacting with Users
JavaScript provides these built-in top-level functions for interacting with the user:
alert(string): Pop-up a box to alert user for important information. The user will have to
click "OK" to proceed. The alert() returns nothing (or undefined).
prompt(string, defaultValue): Pop-up a box to prompt user for input, with an optional
defaultValue. The prompt() returns the user's input as a string. For example,
confirm(string): Pop-up a box and ask user to confirm some information. The user will
have to click on "OK" or "Cancel" to proceed. The confirm() which returns a boolean
value. For example,
// Returns a boolean
parseInt(string), parseFloat(string): parses the given string and returns the numeric
value or NaN (Not-A-Number). The parseInt(str, radix) accepts an optional radix (or
base). For example,
var a = parseInt("88");
console.log('type: ' + typeof a + ', value: ' + a); // type: number,
value: 88
a = parseInt("88.99");
console.log('type: ' + typeof a + ', value: ' + a); // type: number,
value: 88
a = parseInt("14px");
console.log('type: ' + typeof a + ', value: ' + a); // type: number,
value: 14
a = parseInt("Hello");
console.log('type: ' + typeof a + ', value: ' + a); // type: number,
value: NaN
a = parseFloat("88.99");
console.log('type: ' + typeof a + ', value: ' + a); // type: number,
value: 88.99
a = parseFloat("0.5%");
console.log('type: ' + typeof a + ', value: ' + a); // type: number,
value: 0.5
a = parseFloat('Hi');
Number(object): returns the number representation of the object. It works for String
object, as well as many objects such as Date.
isNaN(number): returns true if number is NaN. Useful for checking the output of
parseInt() and parseFloat().
click:
mouseover, mouseout:
load, unload:
The event handler, called oneventname (such as onclick, onmousemove, onload), is the codes
that responses to an event. The event handler is typically attached to the target HTML tag, e.g.,
<!DOCTYPE html>
<!-- "JSEventDemo.html" -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Event Demo</title>
<script>
function say(message) {
alert(message);
}
</script>
</head>
<body>
<h2 onmouseover="this.style.color='red'"
onmouseout="this.style.color=''">Hello</h2>
<input type="button" value="click me to say Hello" onclick="say('Hello')">
<p onclick="say('Hi')">This paragraph can say Hi...</p>
</body>
</html>
5. Objects
5.1 Objects are Everywhere!
JavaScript is object-oriented (OO), and objects are everywhere in JavaScript. Arrays are objects;
functions are also objects; primitives like string and number are auto-box to objects in many
operations. Almost everything in JavaScript can be an object, possibly except the undefined and
null (object)!
It is crucial to understanding objects to be proficient in JavaScript, as they are everywhere, and
they are used extensively in JavaScript plug-ins like jQuery, AngularJS, and etc.
JavaScript, however, does not support all the OO features, so as to keep the language simple.
5.2 Properties and Methods
In conventional object-oriented programming languages (like Java/C++/C#), an object is a
collection of properties and methods under a common name:
Properties (also called variables, attributes): contains values associated with the object.
Methods (also called operations, functions): contains actions that the object can perform.
For example, a Car object has properties such as make, model, price, capacity; and methods
such as startEngine(), move(), brake(), stopEngine().
Unlike full-fledged OO languages, JavaScript is designed on a simple OO paradigm. A
JavaScript object is simply a collection of properties. A property is an association between a
name (or key) and value (i.e., name-value pair or key-value pair). If the value is a function, the
property is known as a method. In other words, JavaScript does not differentiate between
properties and methods like conventional OO languages. A method is simply a property holding
a function.
5.3 Creating Objects via Object Initializer
You can create a new object by directly assign an object literal to a variable, known as Object
Initializer. The syntax is as follows:
var objectName = {
property1: value1,
property2: value2,
......,
......
}
The name-value pairs are separated by commas ','. There is no comma after the last
name-value pair.
The property name could be a string or a number. For string name which is NOT a valid
identifier (an valid identifier begins with an alphabet, underscore or dollar sign; and does
not containing special characters like blank or '-'), you need to enclose the name with
single or double quotes. Otherwise, the quotes are optional. For example,
var objectName = {
name:
'Tan Ah Teck',
age:
21,
optional)
88:
'hello',
'my name':
'Peter',
need to be quoted
'font-size': '14px',
to be quoted
}
Take note that if the property name's string is a proper identifier, you can omit the quotes.
This is commonly practiced by the developers.
A property's value could take all JavaScript types, including primitives (string, number,
boolean), object or function. The property is known as a method, if it holds a function.
JavaScript does not differentiate between variables and methods like conventional OO
languages (Java/C++/C#). A method is simply a property holding a function.
You can remove a property (including method) via the delete aPropertyName.
Operator instanceOf
You can use the instanceOf operator to check if a particular instance belongs to a particular
class of objects, e.g.,
var
now
now
now
now
now = Date();
instanceOf Date;
instanceOf Object;
instanceOf Array;
instanceOf Function;
//
//
//
//
gives
gives
gives
gives
true;
true;
false;
false;
You can use the in operator to check if a particular property belongs to an object, for example,
"PI" in Math;
// gives true
// true
// true
// false
// true
An object's property can hold primitives (number, string). It can also hold an object.
var request = {
type: 'POST',
url: 'apple.php',
data: {
name: 'peter',
id:
8888
}
};
console.log(request.data.name);
console.log(request.data.id);
console.log(request.data);
console.log(typeof request);
console.log(typeof request.type);
console.log(typeof request.data);
// peter
// 8888
// Object {name: "peter", id: 8888}
// object
// string
// object
A JavaScript object's property can also hold a function (or method). You can assign to an
anonymous function or a named function as shown in the following example.
// Create an
var myCircle
radius:
created:
getArea:
return
},
toString:
}
function toString() {
return "Circle {radius: " + this.radius
+ ", created: " + this.created
+ "}";
}
// Invoke methods via the dot operator
console.log(myCircle.getArea());
// 95.03317777109125
console.log(myCircle.toString()); // Circle {radius: 5.5, created: ...}
console.log(myCircle);
// Object {radius: 5.5, created: ...}
console.log(typeof myCircle.getArea);
object type)
console.log(typeof myCircle.toString);
console.log(typeof myCircle.created);
The name (of the name-value pair) can take a string or a number, e.g., var a = {88:'b',
'c':'d', fontSize:'14px'}.
Many developers do not enquote the string name, if it is a valid identifier (a valid identifier
begins with an alphabet, '_' or '$'; and does not contain special characters like blank and '-').
For example, var a = {b:'c', d:'e'} is the same as var a = {'b':'c', 'd':'e'}.
However, you need to enquote a string name if it is NOT a valid identifier, e.g., var a =
{'1b':'c', 'my name':'peter', 'font-size':'14px'}.
The string value must be enquoted; otherwise, it will be treated as a variable name.
Dot Operator vs. Index (Square Bracket) Operator
You can access an object's property via either dot operator or index operator. Dot operator is
commonly used as it is more concise and used in conventional OO languages. But index operator
allows access to properties containing special characters and selection of properties using
variables, which is not feasible with dot operator. For example,
var a = {'font-size':'14px'};
a valid identifier
= {
1.1,
'red',
function() { return radius*radius*Math.PI; }
Establishes the default object for a set of statements. The syntax is:
with (expression) {
statement;
}
As discussed earlier:
An undeclared variable has type of undefined, and its value cannot be referenced.
A declared but uninitialized variable has type of undefined, with a special literal value
of undefined too. [undefined is both a type and a literal value!]
A unallocated object has a special literal value of null. Take note that null is an object!
In boolean expressions, both the null and undefined evaluate to false (together with emptystring "", number 0 and NaN, and boolean false). To check for null value, use value ===
null, as value == null (or !value) returns true for null, undefined, "", 0, NaN, and false
As seen from the above examples, the typeof operator returns the type of a value, which can be
a primitive type (such as number, string, boolean) or object (including function).
The instanceof operator check if the value is an instance of a class.
The .toString() and .valueOf() Methods
console.log(student['age']);
// or student.age
console.log(student.length);
// undefined (It is an Object, not
Array)
console.log(student instanceof Array); // false
Using an Array Object for Associative Array
In JavaScript, we usually create an associative array using a generic object (via the Object
Initializer). You can also create an associative array via Array constructor. For examples,
// Construct an array
var aStudent = new Array();
// Add item with string key - need to quote the string
aStudent['name']
= 'Peter';
aStudent['id']
= 12345;
aStudent['gender'] = 'male';
for (key in aStudent) {
console.log(key + ": " + aStudent[key]);
}
// name: peter
// id: 12345
// gender: male
console.log(aStudent.length);
// Get 0!!!
console.log(aStudent instanceof Array); // true
console.log(typeof aStudent);
// object
In this case, additional properties are added into an Array object as object's properties. The array
has .length of 0, as .length reflects only the numerical indexes! Using an array object for
associative array is not recommended. I describe here for completeness.
6.3 The String Object
JavaScript provides primitive string type. It also provide a String class as a wrapper class for
primitive string. Read "The string Type, Literals and Operations" for primitive string.
A string can be created in two ways:
1. directly assigned a string literal in the form of "..." or '...' to a variable, resulted in a
string primitive.
2. invoke the String object constructor to construct a String object.
For examples,
// Creating a string primitive by assigning a string literal
var str1 = 'Hello';
the constructor
// type: object
// true
// true
A string primitive is "auto-box" to a String object, when you invoke a String object's
methods. For example,
var str = "hello";
// a primitive string
new Date():
new Date(dateTimeStr):
Commonly-used methods:
get/set the date (1-31), month (0-11 for Jan to Dec), year (4-digit year).
getDay():
getTime(), setTime():
00:00:00.
6.7 The Math Object
Commonly-used properties:
E, PI:
SQRT2, SQRT1_2:
Commonly-used methods:
abs(x)
max(x,y), min(x,y)
random():
A variable can be assigned a Function object (called function variable), which takes a special
object type called function. [In JavaScript, an object's type is either function (for Function
object) or object (for any object not a Function).]
For example,
function sayHello(msg) { // Define a 'named' function
console.log(msg);
return msg;
}
sayHello('hello'); // Invoke function with function name
console.log('type: ' + typeof sayHello);
// type: function
console.log(sayHello instanceof Function); // true
console.log(sayHello instanceof Object);
// true
// Assign a variable to a function object
// (without parentheses and argument)
var magic = sayHello;
magic('Hi');
// Invoke function
console.log('type: ' + typeof magic);
// type: function
console.log(magic instanceof Function); // true
console.log(magic instanceof Object);
// true
Anonymous Function
If a function is called only once, you can use an anonymous function, omitting the function
name. Anonymous functions are commonly-used as event handler, e.g.,
// The property "window.onunload" takes a function object, to be called back
// with an event object as argument when onload triggers
window.onload = function(event) {
console.log("run onload handler");
console.log(event.target); // element that triggered the event
}
// Alternative, you can assign to a pre-defined function
function onloadhandler(event) {
console.log("run pre-defined onload handler");
console.log(event.target);
}
window.onload = onloadhandler; // function name only, without argument and
parenthese
// function must be defined before assignment
You can define a inline (anonymous) function and assign it to a variable as follows:
var magic = function() { return "Hello" };
// same as
function magic() { return "Hello" };
Function Constructor
Besides using function keyword, you can also use the Function constructor (with new
operator) to define a Function object. This is not easily understood and, hence, not
recommended.
var magic = new Function("arg1", "arg2", "return arg1 + arg2");
// Same as
//
function magic(arg1, arg2) { return arg1 + arg2; }
// Also same as
//
var magic = function (arg1, arg2) { return arg1 + arg2; }
console.log(magic(55, 66));
console.log('type: ' + typeof magic);
// type: function
console.log(magic instanceof Function); // true
console.log(magic instanceof Object);
// true
7. More on Objects
7.1 Prototype-based vs. Class-based
JavaScript's OO is prototype-based, instead of class-based like Java/C++/C#.
A class-based OO language (such as Java/C++/C#) is founded on concepts of class and instance.
A class is a blue-print or template of things of the same kind. An instance is a particular
realization of a class. For example, "Student" is a class; and "Tan Ah Teck" and "Paul Lee"
are instances of the "Student" class. In a class-based OO language, you must first write a class
definition, before you can create instances based on the class definition. The instances created
have exactly the same properties and methods as the class - no more, and no less.
On the other hand, a prototype-based OO language (such as JavaScript) simply has objects (or
instances). A new object can be constructed based on an existing object as prototype. There is no
class definition, and hence, they are also called class-less OO languages.
In JavaScript:
Every JavaScript object has a prototype. The prototype is also an object. A JavaScript
object is created from a prototype object and gets its initial properties from the prototype.
Every JavaScript object has an internal property called __proto__, which holds its
prototype object. When you define a new object via "Object Initializer" (or new
Object() constructor), its __proto__ is set to a built-in object called
Object.prototype. In other words, the new object uses Object.prototype as its
prototype, and gets its initial properties from Object.prototype. The __proto__
property is not enumerable, i.e, it would not shown up in the for..in loop.
For example,
console.log(myCircle.radius);
console.log(myCircle.getArea());
// 1.1
// 3.8013271108436504
// Check prototype
console.log(myCircle.__proto__ === Object.prototype); // true
console.log(Object.prototype);
// Object.prototype holds an object called Object,
//
which is served as prototype for other objects.
// Object is the only object in JavaScript without a prototype,
//
with its __proto__ sets to null.
console.log(Object.prototype.__proto__); // null
// Object is always sit on top of the so-called prototype chain.
// i.e., myCircle -> Object.prototype -> null
// The Object.prototype contains shared functions such as toString(),
//
valueOf() and hasOwnProperty().
console.log(Object.prototype.toString()); // [object Object]
console.log(Object.prototype.valueOf());
console.log(Object.prototype.hasOwnProperty('toString')); // true
// The newly created objects inherits all the properties from its
prototype.
// For example,
console.log(myCircle.toString()); // invoke Object.prototype.toString()
console.log(myCircle.hasOwnProperty('toString')); // false (inherited,
NOT own property)
console.log(myCircle.hasOwnProperty('radius'));
// true
// Iterating thru all the properties
for (var key in myCircle) {
console.log("key is " + key + ", value is " + myCircle[key]);
}
// key is radius, value is 1.1
// key is getArea, value is function () { return this.radius *
this.radius * Math.PI; }
// true
Any object can be the prototype of new objects. For example, Object is the prototype of
Person; Person is the prototype for Student; Student is the prototype for
UndergraduateStudent. These objects form a so-called prototype chain, i.e.,
UndergraduateStudent -> Student -> Person -> Object -> null. Take note that
Object is always on top of the prototype chain for every JavaScript object.
You can add or remove properties for an object at runtime, which is not permitted in
conventional OO languages.
"this" refers to the current object. this.aPropertyName refers to the property of this object.
Example
Let us define a constructor for our custom Circle objects, with properties radius, created,
getArea() and toString().
// Define a constructor for Circle objects, which takes an argument radius.
// The Circle objects have properties radius and dateCreated, getArea() and
toString().
function Circle(radius) {
this.radius = radius || 1;
// Default is 1, if radius evaluates to
false (e.g., undefined)
this.dateCreated = new Date(); // Assign an object
this.getArea = function() {
// Assign a function object via an inline
function
return this.radius * this.radius * Math.PI;
};
this.toString = toString; // Assign a function object via a named function
}
// true
All the JavaScript constructor function objects (in fact, all function objects) have a special
property called .prototype. By default, it holds an object that can be used as a prototype for
creating new objects.
In the Circle example, the Circle constructor function has a Circle.prototype, which holds
a Circle object to be used as a prototyping object. When a new Circle object is constructed via
the new operator, the newly constructed object's __proto__ property is set to
Circle.prototype.
Adding Shared properties to Constructor's .prototype Property
// true
When you reference a property, JavaScript first checks if the property exists locally (or own
property); otherwise, it checks the prototype chain through the __proto__ property. Recall that
the new constructor() call sets the __proto__ to constructor.prototype. Hence, properties
added into constructor.prototype are available to (and shared by) all the objects prototyped by
this constructor.
In practice, we defines methods (and static variables) in constructor.prototype to be shared by
all objects; while each object maintains its own properties (instance variables).
Looking up the Prototype Chain
Objects in JavaScipt form prototype chains. In the above example, a prototype chain is circle1
-> Circle.prototype -> Object.prototype -> null.
When you reference an object property, JavaScript follow these steps to locate the property:
1. Check if the property exists locally (i.e., own property).
2. Otherwise, check the __proto__ property. This continues recursively up the prototype
chain. The process is called "lookup in the prototype chain".
Hence, in the above example, all the properties in Circle.prototype and Object.prototype
are inherited by circle1.
instanceof Operator
Every object has a __proto__ object property (except Object); every constructor function has a
.prototype property. So objects can be related by 'prototype inheritance' to other objects. You
can test for inheritance by comparing an object's __proto__ to the constructor's .prototype.
JavaScript provides a shortcut: the instanceof operator tests an object against a function and
returns true if the object inherits from the function prototype. For example,
[TODO]
Object.create()
Object.create() lets you create a new object based on the given prototype object. It simply
sets the __proto__ to the given prototype object, so that all properties of the prototype are
available to the new object. Using Object.create(), You do NOT need to define a constructor
function and run new constructor() to create new objects.
var student1 = {
name: 'Peter',
getName: function() { return this.name; }
}
console.log(student1);
// Object {name: "Peter"}
console.log(student1.getName()); // Peter
console.log(student1.hasOwnProperty('name')); // true
// Use Object.create() to create a new object using student1 as the prototype
object
// i.e., set __proto__ to student1
var student2 = Object.create(student1);
console.log(student2);
// Object {} (No own property)
console.log(student2.__proto__); // Object {name: "Peter"} (set prototype
chain)
console.log(student2.__proto__ === student1); // true (same reference)
console.log(student2 === student1);
// false (different reference)
console.log(student2.getName()); // Peter (inherited thru prototype chain)
console.log(student2.hasOwnProperty('name')); // false
student2.name = 'Paul';
console.log(student2);
// Object {name: "Paul"} (added own
property)
console.log(student2.__proto__); // Object {name: "Peter"} (no change)
console.log(student2.getName()); // Paul
console.log(student2.hasOwnProperty('name')); // true
How It Works
[TODO]
7.5 Getter and Setter
In languages like Java, you can declare a variable to be private and define public getter/setter
to access the private variable. JavaScript does not really support private access?! But you can
also define ordinary methods getXxx() or setXxx() as getter/setter like Java.
Moreover, in JavaScript, you can define getter/setter as properties instead of methods in one of
the following two ways:
1. via built-in functions Object.defineProperties() or Object.defineProperty();
2. inside the "object initializer" via keywords get and set.
Example 1: Define Getters/Setters via Object.defineProperties() or Object.defineProperty()
// Define constructor for Circle objects
function Circle(radius) {
this._radius = radius || 1;
}
// Define getter/setter via Object.defineProperties() in constructor.prototype
Object.defineProperties(Circle.prototype, {
// Getter/Setter for radius
'radius': {
get: function() { return this._radius; },
Notes:
1. The Objet.defineProperties() allows you to define multiple properties; while
Objet.defineProperty() for a single property.
2. You invoke the getters/setters like properties with assignment operator, instead of via
function call.
Example 2: Define Getter/Setter inside the Object Initializer
// Define an object with getters and setters
var myCircle = {
_radius: 1.1,
get radius() { return this._radius; },
set radius(radius) { this._radius = radius; },
get area() { return this._radius * this._radius * Math.PI; },
get circumference() { return 2 * this._radius * Math.PI; }
}
// Test
console.log(myCircle.radius); // 1.1 (Test getter)
myCircle.radius = 2.2;
// (Test setter)
console.log(myCircle.radius); // 2.2
console.log(myCircle.area);
// 15.205308443374602
console.log(myCircle.circumference); // 13.823007675795091
Notes:
1. The getter/setter are defined inside Object Initializer via keywords get and set with a
rather strange syntax, as shown in the example.
All JavaScript objects inherited a special property called .constructor, which contains a
reference to the function that created the object. For example,
// Construct an Array object
var months = ['jan', 'feb', 'mar'];
console.log(months.constructor); // Array()
console.log(months);
// ["jan", "feb", "mar"]
// Create another Array object by invoking the constructor of the first
object.
var days = months.constructor('mon', 'tue', 'wed')
console.log(days);
// ["mon", "tue", "wed"]
DOM Level 2 (DOM2) (W3C Nov 2000) and DOM Level 2 HTML (HTML DOM2)
(W3C Jan 2003)
DOM Level 3 (DOM3) (W3C Apr 2004): yet to be fully supported by browsers.
jQuery is much better in selecting and manipulating DOM element. You should use jQuery in
production. I keep these sections here for completeness.
8.1 Finding and Selecting Elements
In JavaScript, we often use DOM API to select elements within the current document, so as to
access or manipulate their contents. The most commonly-used functions are:
Descripti
Example
on
Returns
the
<input type="text" id="foo">
element var elm =
document.getElementById(anId)
with the document.getElementById("foo");
var input = elm.value;
given
unique id.
Returns
an array <input type="text">
of
var elms =
document.getElementsByTagName(aTagNa
elements document.getElementByTagName("in
me)
with the put");
var input = elms[0].value;
given tag
name.
Returns
an array
of
<input type="text" class="bar">
var elms =
elements
document.getElementsByClassName(aCla
document.getElementByClassName("
with
the
ssName)
bar");
given
var input = elms[0].value;
Function
class
attribute
name.
document.getElementsByName(aName)
Returns
an array
of
elements
with the
given
name
attribute.
<input type="checkbox"
name="gender" value="m">Male
<input type="checkbox"
name="gender" value="f">Female
var x =
document.getElementsByName("gend
er");
for (var i = 0; i < x.length; +
+i) {
if (x[i].checked) {
value = x[i].value;
break;
}
}
The above functions select element(s) based on the unique id, name attribue and tag-name.
HTML 5 further defines two function that can select elements based on class attribute (which is
used extensively by CSS in the class-selector):
Function
Description
Example
Returns the first element with the given [TODO]
document.querySelector(aClassName)
class attribute.
Returns an array of elements with the [TODO]
document.querySelectorAll(aClassName)
given class attribute.
Beside the above selection functions, there are many other selection functions available.
However, I strongly recommend that you stick to the above functions. I listed below the other
function below for completeness.
1. document.images returns an array of all <img> elements, same as
document.getElementsByTagName("img").
2. document.forms: return an array of all <form> elements.
3. document.links and document.anchors: return all the hyperlinks <a href=...> and
anchors <a name=...> elements. [To confirm!]
8.2 Manipulating Element's Content through the innerHTML Property
You can access and modify the content of an element via the "innerHTML" property, which
contains all the texts (includes nested tags) within this element.
For example,
<p id="magic">Hello, <em>Paul</em></p>
<script>
var elm = document.getElementById("magic");
// Read content
alert(elm.innerHTML);
// Hello, <em>Paul</em>
// Change content
elm.innerHTML = "Good day, <strong>Peter</strong>";
alert(elm.innerHTML);
// Good day, <strong>Peter</strong>
</script>
"innerHTML" is the most convenient way to access and manipulate an element's content.
However, it is not a W3C standard, but it is supported by most of the browsers.
8.3 DOM Tree & Nodes
W3C recommends that you access and manipulate HTML elements via the DOM tree and nodes.
However, it is really an overkill for writing simple JavaScripts. I present them here again for
completeness.
When a browser loads an HTML page, it builds DOM models a web page in a hierarchical treelike structure composing of nodes, resembling its HTML structure.
An example of an HTML document with the corresponding DOM-tree is given follow. Take note
that the text content of an element is stored in a separate Text node.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>DOM Tree</title>
</head>
<body>
<h2 onmouseover="this.style.color='red'"
onmouseout="this.style.color=''">Testing</h2>
<p>welcome to <i>JavaScript</i>...</p>
</body>
</html>
Load the web page onto Firefox, and use the firebug to inspect the DOM tree.
A DOM-tree comprises the following types of nodes:
1. Document Node: the root node representing the entire HMTL document.
2. Element node: represents an HTML element (or tag). An element node may have child
nodes, which can be either element or text node. Element node may also have attributes.
3. Text Node: contains the text content of an element.
4. Others: such as comment, attribute.
A DOM node has these properties:
nodeName:
nodeType:
parentNode:
contain the name of the node, which is read-only. The nodeName for an
Element node is the tag-name; nodeName for the Document node is #document;
nodeName for Text nodes is #text.
for Text node is the text contained;
an integer indicating the type of the node, e.g., Element (1), Attribute (2), Text
(3), Comment (8), Document (9).
reference to parent node. There is only one parent node in a tree structure.
childNodes:
firstChild, lastChild:
prevSibling, nextSibling:
Take note of the difference between singular and plural terms. For example, parentNode refer to
the parent node (each node except root has one and only one parent node), childNodes holds an
array of all the children nodes.
The root node of the DOM tree is called document. The root node document has only one child,
called document.documentElement, representing the <html> tag, and it acts as the parent for
two child nodes representing <head> and <body> tags, which in turn will have other child nodes.
You can also use a special property called document.body to access the <body> tag directly.
For example, you can use the following node property to access the Text node "Welcome to " in
the above example:
document.documentElement.lastChild.childNodes[1].firstChild.nodeValue; //
"Welcome to "
document.body.lastChild.firstChild.nodeValue;
// same
as above
Example
The following JavaScript lists all the nodes in the <body> section, in a depth-first search manner,
via a recursive function.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>DOM Tree</title>
<script>
function printNode(node) {
document.writeln("Node name=" + node.nodeName + ", value=" +
node.nodeValue + ", type=" + node.nodeType + "<br>");
if (node.hasChildNodes()) {
var childs = node.childNodes;
for (var i = 0; i < childs.length; i++) {
printNode(childs[i]);
}
}
}
</script>
</head>
<body onload="printNode(document.body)"><h2
onmouseover="this.style.color='red'"
onmouseout="this.style.color=''">Testing</h2><p>welcome to
<i>JavaScript</i>...</p></body>
</html>
Node
Node
Node
Node
Node
Node
Node
Node
Accessing the HTML element via Node interface may not be too useful nor practical for
JavaScript applications, as you need to know the actual topological structure of the DOM-tree.
Furthermore, some browsers (e.g., firefox) may create extra Text nodes to contain the white
spaces between tags.
8.4 Text Node
DOM models the texts enclosed by HTML tags as a separate text node. It cannot have child
node. To retrieve the text content, you could the property nodeValue. For example,
<p id="magic">Hello</p>
......
console.log(document.getElementById("magic").firstChild.nodeValue);
document.getElementById("magic").firstChild.nodeValue = "Hi"; // text change
to "Hi"
For example,
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test Attributes</title>
</head>
<body>
<p id="magic1" align="left">Hello</p>
<p id="magic2" align="center">Hello, again.</p>
<script type=text/javascript>
var node = document.getElementById("magic1");
document.writeln(node.align);
// Get attribute "align"
node.align = "center";
// Set attribute "align" to a new value
node = document.getElementById("magic2");
document.writeln(node.getAttribute("align"));
node.setAttribute("align", "right");
</script>
</body>
</html>
aNode.hasChildNodes(): returns true if this node has at least one child node.
aNode.cloneNode():
Creating a New Element (createElement()) and Text Node (createTextNode()), Appending a Node
(appendChild())
To create new text node, you can use document.createTextNode(text) to create a standalone
text-node, followed by an anElementNode.appendChid(aTextNode) to append the text node to
an element.
You can remove a child node from a parent node via aParentNode.removeChild(aChildNode).
For example, let remove the last <p> from <body>.
<body>
<p>Hello 1</p>
<p>Hello 2</p>
<p id="magic">Hello 3</p>
<script>
var elm = document.getElementById("magic");
alert(elm.innerHTML);
document.body.removeChild(elm);
</script>
</body>
The document object is the root node of the DOM-tree. It can be used to access all the elements
in an HTML page.
It contains these properties:
respectively.
response header.
containing the
clear():
open(), close():
The event handler can be a single JavaScript statement, a series of JavaScript statements
(separated by semicolon), or most often, a function call. For example,
<!-- Event handler calls built-in functions -->
<body onload="alert('welcome')" onunload="alert('bye')">
<!-- Event handler calls a user-defined function -->
<script>
function myHandler(event) {
alert(event);
}
</script>
<input type="button" value="click me" onclick="myHandler()">
<!-- Event handler composes of JavaScript statement(s) -->
<h1 onmouseover="this.style.color='red'; this.style.backgroundColor='black'"
onmouseout="this.style.color='';
this.style.backgroundColor=''">>Hello</h1>
You can also define an event handler in script by assigning a Function object (without
parentheses) to an event handler. For example,
<!-- Event handler assigned via DOM object instead of inside HTML tag -->
<p id="magic">Welcome</p>
<script>
document.getElementById("magic").onclick = myHandler; // function name
without the parentheses
</script>
Event
Handler
onclick
submit
onsubmit
reset
onreset
select
onselect
keypress
onkeypress
Description
HTML Element
<form>, <input
type="submit">
<form>, <input
type="reset">
<textarea>, <input
type="text">
document, image, link,
textarea
keydown
keyup
mousedown
mouseup
mouseover
mouseout
mousemove
onkeydown
onkeyup
onmousedown
onmouseup
onmouseover
onmouseout
onmousemove
load
onload
unload
onunload
blur
onblur
change
onchange
focus
onfocus
drapdrop
ondrapdrop
move
resize
abort
onmove
onresize
onabort
error
onerror
<body>, <frameset>,
<img>
<body>, <frameset>
window, frame
[To Check]
9.3 The Event object
The event handlers are passed one argument, an Event object, which described the event and its
current states. You can use it to determine where an event originated from and where it currently
is in the event flow.
The following properties are available to all the Event object:
type: A string
eventPhase:
integer 1 for captured, 2 for at the target, and 3 for bubbling phase.
Mouse-Related Events
button:
clientX, clientY:
screenX, screenY:
Including keyup, keydown and keypress. For key-related events, the Event object provides
these additional properties:
keyCode: ASCII
also pressed.
clientX, clientY:
screenX, screenY:
where eventType is pre-defined event name such as mouseover, mouseout, click, etc;
functionName is the event handler; useCapture is a boolean flag which specifies at which
phase of the event flow (capture or bubble) the event handler will be called.
For example,
<p id="magic">Hello</p>
......
<script>
var element = document.getElementById("magic");
element.addEventListener('mouseover', function() { this.style.color='green';
}, false);
element.addEventListener('mouseout', function() { this.style.color=''; },
false);
</script>
Event listeners can be added to any node, even text nodes (which you could not assign event
handlers to as they have no attributes).
There are two phases of event flow: a capture phase followed by a bubbling phase.
1. Event Capture phase: The event first flows down from the document root to the target
element that trigger the event.
2. Event Bubbling phase: the event then bubbles up from the target element to its parent
node, all the way back to the document root.
For each event type, you could define an event handler for the capture phase (triggered as event
flows down from the root to the target element), and another event handler for the bubbling
phase (triggered when the event bubble up from the target element to the root).
Example: [TODO]
platform:
others.
Operating system.
Identified the browser.
[TO CHCEK]
10.2 The window object
The window object represents an open window in a browser. It is the top-level object in the
JavaScript hierarchy. All top-level properties and methods such as alert(), prompt(),
parseInt() belongs to the window object. The window object is also the default object. That is,
alert() is the same as window.alert(). A window object is created automatically with every
<body> or <frameset> tag.
[TODO]
/^[0-9]+$/ (or /^\d+$/) matches strings with 1 or more digits (/.../ delimits the
regex, ^ matches the begin position, $ matches the end position, [0-9] matches a
character in the range of '0' to '9', + for zero or more repetition, \d matches a digit).
/^[0-9]{5,8}$/
/^[a-zA-Z]+$/
9. Call the constructor of the built-in RegExp object (less frequently-used), for example,
10. var pattern = new RegExp("[1-9][0-9]*|0");
11. console.log(pattern);
// /[1-9][0-9]*|0/
12. var anotherPattern = new RegExp("\w+\.(jpg|gif|png)", "gi");
pattern, modifier
console.log(anotherPattern); // /w+.(jpg|gif|png)/gi
Modifiers
//
g: to perform a global search (return all matches instead of the first match by default),
You can use $1 to $99 to refer to the parentheses back references, or RegExp.$1 to RegExp.$99
object properties.
Example 1: Swap first and second words
var pattern = /(\S+)\s+(\S+)/;
var input = 'Hello world';
// Swap the first and second words
input = input.replace(pattern, '$2 $1');
console.log(input); // world Hello
aRegExpObj.test(aStr): Tests this regex against the given string. Returns boolean true or
false.
aStr.search(aRegex): Search this string for the given regex pattern. Returns the beginning
position of the matched substring or -1 if there is no match.
aStr.replace(aRegex, replacement): Search the string for the given regex pattern. If found,
replaces the matched substring with the replacement string.
aStr.split(aRegex): Split this string using the delimiter pattern defined in the given regex.
Returns an array of strings containing the splitting parts.
The data contains one key:value pair, with key of members and value of an array of three
objects. Each object has three properties: name (string), age (number) and isMarried (boolean).
Notes:
JSON's key fields must be double-quoted as shown; while in JavaScript, the quotes are
optional if the key is a valid identifier.
JSON.parse()
You can parse a JSON-formatted string to a JavaScript object via built-in function
JSON.parse(). For example,
var jsonStr = '{ "members": ['
+ '{"name":"Paul", "age":50, "isMarried":true},'
+ '{"name":"Anna", "age":40, "isMarried":false},'
+ '{"name":"Peter", "age":30, "isMarried":true}'
+ ']}';
var obj = JSON.parse(jsonStr);
console.log(obj); // Object {members: Array[3]}
console.log(obj.members[0].name); // Paul
JSON.stringify()
[TODO]
All modern browsers implement the SOP, which restricts a script (or web font) loaded from one
server to access another server. Two pages has the same origin if they have the same protocol
(e.g., HTTP, HTTPS, FILE, FTP are different protocols), host and port.
SOP is used as a means to prevent so-called Cross-site Request Forgery (CSRF) attacks. Suppose
that you are logged on to Facebook (successfully authenticated) and visit a malicious website in
another domain on another browser tab. Without the SOP, JavaScript from the malicious website
can do anything to your Facebook account that you are allowed to do, because your current
browser session has been authenticated on another browser tab. With the SOP, only scripts
coming from Facebook can work on your Facebook account.
// Use Ajax to load a page from a different domain into current page,
supposing your origin is http://localhost.
$('#magic').load("http://www.google.com");
// Error: XMLHttpRequest cannot load http://www.google.com/.
// No 'Access-Control-Allow-Origin' header is present on the requested
resource.
// Origin 'http://localhost' is therefore not allowed access.
In other words, SOP disallows one script to perform HTTP GET/POST request to another
domain to prevent Cross-site Request Forgery (CSRF) attacks.
Exceptions to SOP are:
Others, such as <a>, <video>, <audio>, <object>, <embed>, <applet>, <frame> and
<iframe>.
JSONP
You can send a cross-site request to a JSONP-enabled website via the <script> tag as follows:
<script src="http://www.anotherdomain.com/hello.json?
callback=mycallback"></script>
With JSON, the server returns a JSON string (e.g., {"foo": "bar"} ), which will be evaluated and
produce nothing.
Under JSONP, the server is supposed to wrap the JSON object under the callback function
provided in the request parameter. That is,
mycallback({"foo": "bar"});
You can then write your callback function to perform your operations, e.g.,
function mycallback(data) {
// process the data object
console.log(data.foo);
}
Hence, when the script is loaded, it'll be evaluated, and your function will be executed - as a
cross-domain request!
With JSONP, it is entirely up to your server to decide whether to support cross-domain request
by padding the JSON response.
12.3 Cross-Origin Resource Sharing (CORS)
CORS is the latest W3C standard for cross-domain request, carried out via special HTTP
headers.
1. The browser sends the request with an Origin HTTP header, e.g.,
2. Origin: http://www.anotherdomain.com
3. An error page if the server does not allow the cross-origin request.
With CORS, it is entirely up to your server to decide whether to support cross-domain request
(similar to JSONP).
13. Miscellaneous
13.1 Task Scheduling via Timeout
Two methods, setTimeout(codes, milliseconds) and clearTimeout(timeoutName) are
provided to schedule a piece of codes to be executed after a specified milliseconds.
var task = setTimeout("alert('Hello')", 10000);
The variable task permits you to cancel the scheduled time event before timeout if desires:
cancelTimeout(task);
Operator
() [] .
! ~ - ++ -*/%
+-
Bitwise Shift
Relational
Equality
Bitwise AND
Bitwise XOR
Bitwise OR
Logical AND
Logical OR
Ternary (Shorthand if-else)
Assignment
Comma (separate parameters)
In JavaScript, throw can throw any types: primitive (string, number, boolean) or object.
try-catch-finally
Execution begins at the try-block. If none of the statements in the try-block throws an exception,
the catch-block is skipped.
However, if one of the statement in the try-block throw an exception, the rest of the statements in
the try-block is skipped, and execution branches to the catch-block to process the exception. In
JavaScript, there is only one catch-block, which catches all the exceptions.
The optional finally-block is always executed, after try or catch, for performing house keeping
task, such as closing the files. The program will continue into the next statement, if it is not
terminated.
The try-catch-finally construct has the following benefits:
1. Separating of exception handling logic from the main logic. You do not need to use many
if-else in the main logic to check for exception.
2. Allow graceful termination of the program, handled by the catch-block.
3. ....
Example [TODO]
13.5 Execute JavaScript Statement from Browser's Address Bar
You can issue You can execute JavaScript from Firefox's navigator toolbar or Internet Explorer's
address bar, via pseudo-protocol javascript:statement. For example,
javascript:alert('Hello');
javascript:alert(document.title);alert('Hello, again')
javascript:document.title
The statement can access variables and objects on the current document.
The JavaScript statement used in a javascript: URL should not return any value. For example,
alert() does not return a value (or returns undefined). If it returns an explicit value, the
browser loads a new page and places the returned value in the body of the page.
You can use the void operator to stay in the same page. void evaluates its expression, and
returns undefined. For example,
javascript:void(x=5)
You can bookmark the javascript statement (someone called them bookmarklets). For example,
you can write a bookmarklet to change the background color of a web page, so that the web page
is easier to read.
javascript:void(document.body.style.background='#FFF');
}
// Invoke the outer function and save the return function in an variable
var f1 = outer(3);
// Invoke the inner function
console.log('sum:' + f1(10));
// x:3 y:8 z:10 sum:21
// Invoke the inner function
console.log('sum:' + f1(20));
// x:3 y:8 z:20 sum:31
// Take note that the value of x:3 remains the same across the
invocations,
//
which is provided by the outer function's argument
// Invoke the outer function again with a different argument
var f2 = outer(9);
// Invoke the inner function
console.log('sum:' + f2(30));
// x:9 y:8 z:30 sum:47
// Invoke the inner function
console.log('sum:' + f2(40));
// x:9 y:8 z:40 sum:57
// Take note that the value of x:9 remains the same across the
invocations,
//
which is provided by the outer function's argument
Each invocation of the outer function creates a so-called closure, which is the inner function with
a set of variables together with an environment that binds those variables.
As seen from the above example, the value of x and y in the outer function remains the same for
each invocation, in the return inner function. However, each invocation create a new closure with
its set of values. A closure is similar to an object instance where the variables' value are already
fixed.