IMPORTANT:
Some of the content here is a personal summary/abbreviation of contents on the Mozilla JavaScript Guide and Runoob JavaScript Guide. Feel free to refer to that site if you think some of the sections written here are not clear.
Introduction to JavaScript
A brief history of JavaScript is omitted, but some key points are listed here.
ECMAScript
ECMAScript (ES) is a standard defined for scripting languages, and JavaScript is an implementation of it.
- so this means that JavaScript is like Python, it does not need a compiler
 
Browser Engines
Here I refer to engines for executing JavaScript. Different browsers execute JavaScript differently, if they have a different engine. For example:
- Chrome uses v8 (currently the fastest)
 - Firefox uses SpiderMonkey
 - …
 
Components of JavaScript
On a high level, JavaScript implements the following three components:
where:
- ECMAScript - the standard of scripting languages
 - DOM - controls webpage activities
 - BOM - controls browser activities
 
Object Oriented Programming
Similar to programs such as Java, it is a OOP.
Basics
This guide assumes some prior knowledge of HTML and CSS, as well as any another programming language, and it will only lists summaries/key points of what I have learnt.
Basic Usages
For controlling website related events/content, JavaScript manipulates the document object:
JavaScript is like pieces of code that gets injected into your html during the “compile” time. Therefore, upon testing, the precedence is as from top to bottom of your code:
for example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- JavaScript goes into the script tag -->
<script>
document.write("This comes first");
</script>
</head>
<body>
<script>
document.write("This comes second");
</script>
</body>
</html>
JavaScript can be inserted in any position (
head,body) of the html file, using the<script>tagupon testing, precedence of running related JavaScript is:
first it searches from current line towards the bottom
then it searches in the
<body>tagfinally, it searches in the
<head>tagfor example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function myfunction() {
document.getElementById("1").innerHTML="Hi,1";
}
</script>
</head>
<body>
<script>
function myfunction() {
document.getElementById("0").innerHTML="Hi,0";
}
</script>
<p id="0">
test
</p>
<p id="1">
test
</p>
<button type="button" onclick="myfunction()">点击这里</button>
</body>
</html>where:
only
1
2
3
4
5<script>
function myfunction() {
document.getElementById("0").innerHTML="Hi,0";
}
</script>will be executed
Using
document.write()during the HTML stream/“compilation”, then it is equivalent of appending to the current html content. However, usingdocument.write()after your page is loaded, it will overwrite the entire webpage.for example:
1
2
3
4
5
6
7
8
9
10
11<script>
function myfunction(){
document.write("This will overwrite the entire page");
}
document.write("<h1>This is a paragraph</h1>");
document.write("<p>This is another paragraph</p>");
</script>
<p >
You only use <strong>document.write during the HTML output stream</strong>。
</p>
<button type="button" onclick="myfunction()">Click here</button>
Outputting Data
window.alert()弹出警告框。document.write()方法将内容写到 HTML 文档中。innerHTML写入到 HTML 元素。console.log()写入到浏览器的控制台。
Basic Syntax
Variable Identifiers are case-sensitive and uses the Unicode character set.
For example, the word Früh is legal as variable name.
1
let Früh = "foobar";
However, similar to Java and C, you can only use characters, numbers and symbols
_$.
Statements are separated by semicolons (;).
- For example, the variable declaration above.
 - A semicolon is not necessary after a statement if it is written on its own line. However, it is considered the best practice to use a 
;for every statement. 
Comments is pretty much the same in Java/C++ and other languages.
An example is the easiest:
1
2
3
4
5
6
7// a one line comment
/* this is a longer,
* multi-line comment
*/
/* You can't, however, /* nest comments */ SyntaxError */
Variable Declarations - JavaScript has three kinds of variable declarations.
varDeclares a variable, optionally initializing it to a value.
- For example, 
var x = 42;. This syntax can be used to declare both local and global variables, depending on the execution context. 
- For example, 
 
vardeclarations, wherever they occur, are created (but not assigned) before any code is executed. This is called hoisting
letDeclares a block-scoped, local variable, optionally initializing it to a value.
- For example, 
let y = 13. This syntax can be used to declare a block-scope local variable. 
- For example, 
 constDeclares a block-scoped, read-only named constant.
however,
constonly protects the assignment of the variable. Fields of theconstwill not be protected (similar toconstinC):1
2const MY_OBJECT = {'key': 'value'};
MY_OBJECT.key = 'otherValue'; // is allowed
Undeclared Global Variable
- For example, 
x = 42. This form creates an undeclared global variable. It also generates a strict JavaScript warning 
- For example, 
 
Undefined Variables
A variable declared using the
varorletstatement with no assigned value specified has the value ofundefined.- An attempt to access an undeclared variable results in a 
ReferenceErrorexception 
- An attempt to access an undeclared variable results in a 
 undefinedcan be used to determine whether a variable has a valuefor example:
1
2
3
4
5
6var input;
if (input === undefined) {
doThis();
} else {
doThat();
}
undefinedbehaves the same asfalsewhen used in a Boolean contextfor example:
1
2var myArray = [];
if (!myArray[0]) myFunction();where:
myFunctionexecutes ifmyArrayelement isundefined
undefinedvalue converts toNaNwhen used in numeric context.for example:
1
2var a;
a + 2; // Evaluates to NaN
null Variable
nullbehaves as0in numeric contexts and asfalsein Boolean contexts.this means it’s “safer” than
undefinedfor example:
1
2var n = null;
console.log(n * 32); // Will log 0 to the console
Variable Scope
global variable is available to any other code in the current document
- variable declared outside of any function
 
block-scope variable is available to any other code in the current block
a variable declared with
varis available within the function/global scopefor example:
1
2
3
4
5if (true) {
var x = 5; // available to the entire outer function.
// In this case, it will be global context
}
console.log(x); // x is 5
a variable declared with
letis available within the current code blockfor example:
1
2
3
4if (true) {
let y = 5; // only available within this if block
}
console.log(y); // ReferenceError: y is not defined
In short:
- variable declaration
 varfollows the rule specified above- variable declaration with
 letorconsthave a more limited scope and behaves in the same way
- except that
 constis ready only and requires a value at initialization time- cannot declare a
 constwith the same name as a function or variable in the same scope.
Variable Hoisting
Hoisting refer to the ability of referring to a variable declared later, without getting an exception.
- Variables in JavaScript are, in a sense, “hoisted” (or “lifted”) to the top of the function or statement.
 
However, variables that are hoisted return a value of undefined.
In ECMAScript 2015,
letandconstare hoisted as well but not initialized.for example:
1
2console.log(x); // ReferenceError
let x = 3;
Variable hoisting example:
1  | var myvar = 'my value';  | 
can be interpreted as:
1  | var myvar = 'my value';  | 
Function Hoisting
For functions, the idea is the same:
- only declaration/initialization are hoisted, but the actual value/function expressions are not.
 
For example:
1  | baz(); // TypeError: baz is not a function  | 
would be the same as
1  | var baz;  | 
Using Global Variables
Global variables are in fact properties of the global object.
- In web pages, the global object is 
window(and inside that browserwindow, you have your HTML page) 
This means:
- The
 windowobject is the object representing the entire browser window- all JavaScript global variables are
 fieldsof thewindowobject
- in fact, this includes the HTML DOM
 documentobjectwindow.document.getElementById("header");is the same asdocument.getElementById("header");- all JavaScript global functions are
 fieldsof thewindowobject
Consequently, you can access global variables across scripts loaded inside the same browser window
Data Types
There are seven primitive types, and Object
boolean.trueandfalse. (case sensitive)null. A special keyword denoting a null value (case sensitive).undefined. A top-level property whose value is not defined.Number. An integer or floating point number. For example:42or3.14159.[BigInt. An integer with arbitrary precision. For example:9007199254740992n.String. For example: “Howdy”Symbol(new in ECMAScript 2015). A data type whose instances are unique and immutable.
Data Type Conversion
JavaScript is a dynamically typed language. This means:
- you don’t have to specify the data type of a variable when you declare it.
 - data types are automatically converted as-needed during script execution.
 
For example:
You can do the follows:
1
2
3var answer = 42;
// some other code
answer = 'Thanks for all the fish...';
String Concatenation with + Operator
This is similar in other languages, except that:
- numbers are only converted to strings with the 
+operator. In the other cases, strings will be converted to number 
For example:
'37' + 7 // "377", using the + operator '37' - 7 // 30, not using + operator <!--19--> An integer between `2` and `36` that represents the *radix* (the **base** in mathematical numeral systems) of the `string`. Be careful—this does ***not*** default to `10`! - **returns** the parsed number or `NaN` when - the `radix` is smaller than `2` or bigger than `36`, or - the **first non-whitespace character** cannot be converted to a number.parseFloat()parseFloat(string) <!--20-->
Floating-pointA floating-point literal can have the following parts:
[(+|-)][digits].[digits][(E|e)[(+|-)]digits]for example:
1
2
3
43.1415926
-.123456789
-3.1E+12
.1e-23
Boolean- Boolean type has two literal values: 
trueandfalse. 
- Boolean type has two literal values: 
 Stringboth single quote and double quote works
for example:
1
2
3"John Doe"
'John Doe'
Templateit can be used as interpolation like
%sinside a string forCfor example:
1
2var name = 'Bob', time = 'today';
var interpolated = `Hello ${name}, how are you ${time}?`
or, it can be used for forming a multiline strings
for example:
1
2
3
4
5var poem =
`Roses are red,
Violets are blue.
Sugar is sweet,
and so is foo.`
Arrayelement inside an array can be of any type, and different elements of the same array can be of different types
empty value in an array is automatically made
undefined(trailing comma will be ignored)for example:
1
[40, "Hi", 1, 5, , 25, true] // undefined between 5 and 25
RegExA regex literal is a pattern enclosed between slashes.
for example:
1
var re = /ab+c/;
Objecta list (map) of zero or more pairs of property names and associated values of an object, enclosed in curly braces (
{}).for example:
1
{firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"}
or:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17function person(firstname,lastname,age,eyecolor)
{
this.firstname=firstname;
this.lastname=lastname;
this.age=age;
this.eyecolor=eyecolor;
this.changeName=changeName;
// method of type person
function changeName(name)
{
this.lastname=name;
}
}
myMother=new person("Sally","Rally",48,"green");
myMother.changeName("Doe");
Objects
The idea is similar with most OOP, yet:
Properties of JavaScript objects can also be accessed or set using a bracket notation
- note that all keys in the square bracket notation are converted to string unless they’re Symbols
 
you can enumerate the properties of an Object
For Example
1  | // four variables are created and assigned in a single go,  | 
where:
- in the above code, when the key 
objof typeObjectis added to themyObj, JavaScript will call theobj.toString()method, and use this result string as the new key. 
For Example: Iterating Over All Properties
1  | function MyObj(){  | 
and the output is:
1  | myObj.name = Jason  | 
Creating new Objects
In summary, you can create a new object using:
- object initializers
 - constructor functions
 Object.createmethod
Object Initializers
This would basically be the same as C and C++
1  | var obj = { property_1: value_1, // property_# may be an identifier...  | 
where:
objis the name of the new object,- each 
property_iis an identifier (either a name, a number, or a string literal) - each 
value_iis an expression whose value is assigned to theproperty_i. 
Note
- Identical object initializers create distinct objects that will not compare to each other as equal. In fact, those objects are created as if a call to
 new Object()were made; that is, objects made from object literal expressions are instances ofObject.
Constructor Functions
This would be the same as most OOP:
- Define the object type by writing a constructor function. 
- There is a strong convention, with good reason, to use a capital initial letter.
 
 - Create an instance of the object with 
new. 
For Example
1  | function Car(make, model, year) {  | 
Note
- since the assignment does not check types, you can in fact pass in anything you want.
 
- for example,
 makecould refer to an Object
Object.create Method
This is useful in the sense that:
- it allows you to choose the prototype object for the object you want to create, without having to define a constructor function.
- The object being inherited from is known as the prototype, and the inherited properties can be found in the 
prototypeobject of the constructor. (see [Prototype Chain](#Prototype Chain)) 
 - The object being inherited from is known as the prototype, and the inherited properties can be found in the 
 
1  | // Animal properties and method encapsulation  | 
Enumerate the Properties of an Object
there are three native ways to list/traverse object properties:
for...inloopsThis method traverses all enumerable properties of an object and its [prototype chain](#Prototype Chain).
Object.keys(o)This method returns an array with all the own (not in the prototype chain) enumerable properties’ names (“keys”) of an object
o.Object.getOwnPropertyNames(o)This method returns an array containing all own properties’ names (enumerable or not) of an object
o.
For Example: Object.keys(o)
1  | // simple array  | 
For Example: Object.getOwnPropertyNames()
1  | var obj = { 0: 'a', 1: 'b', 2: 'c' };  | 
Prototype Chain
A prototype of an object can be understood as the “parent” of the object (like in Java)
- so that properties to be inherited goes in the 
prototypefield 
In JavaScript, functions are able to have properties/fields. All functions have a special property named prototype.
- There is one exception that arrow function doesn’t have a default prototype property
 
For Example
1  | function doSomething(){}  | 
and the output is:
1  | constructor: ƒ doSomething()  | 
At this point, this means you can add properties to a function in two ways:
- add the property to the function directly
 - instantiate it as an Object and add a property
- Calling a function with the 
newoperator returns an object that is an instance of the function. Properties can then be added onto this object. 
 - Calling a function with the 
 
1  | function doSomething(){}  | 
this produces the following:
1  | prop: "some value"  | 
This tells us three things:
the
__proto__ofdoSomeInstancingisdoSomething.prototype.constructor and its “superclass“ information is stored in its
__proto__field- in the above, the constructor is 
doSomething(), and its “superclass” isObject 
- in the above, the constructor is 
 There is a prototype chain that holds property of things, which is used for property/field look up
If
doSomeInstancingdoes not have the property, then the browser looks for the property in the__proto__ofdoSomeInstancing(a.k.a.doSomething.prototype). If the__proto__ofdoSomeInstancinghas the property being looked for, then that property on the__proto__ofdoSomeInstancingis used.for example:
1
2
3
4
5
6function doSomething(){}
doSomething.prototype.foo = "bar";
var doSomeInstancing = new doSomething();
doSomeInstancing.prop = "some value";
console.log(doSomeInstancing.foo); // returns "bar"
Defining Methods
Methods are defined the way normal functions are defined, except that they have to be assigned as the property of an object.
For Example: Object Created using Initializer
1  | var person = {  | 
For Example: Objects Created using Constructor
1  | function MyObj(){  | 
Combing the above two, it means you can attach any function to any type as you want, by simply assigning the function as a property (hence becoming a method).
- provided that you know something about the object
 
Getters and Setters
In summary, getters and setters are functions with a special keyword that can be either
- defined using object initializers, or
 - added later to any object at any time using a getter or setter adding method.
 
However, there is one extra restriction on getter/setter:
- the getter method must not expect a parameter
 - the setter method expects exactly one parameter
 
Note
- in a sense, getter and setters are more like “computable” fields rather than methods when executing.
 
For Example: Getter and Setter for Object Initializers
1  | var o = {  | 
which would be the same as:
1  | var o = { a: 0 };  | 
Deleting Properties
You can remove a non-inherited property by using the delete operator. The following code shows how to remove a property.
1  | var myobj = new Object;  | 
Comparing Objects
Two distinct objects are never equal, even if they have the same  properties. Only comparing the same object reference with itself yields true.
Reminder
- Strict equal (
 ===) Returnstrueif the operands are equal and of the same type.
For Example
1  | // Two variables, two distinct objects with the same properties  | 
and only:
1  | // Two variables, a single object  | 
Control Flows
Since for most languages, the idea for control flows are the same, this section only discusses some important/interesting ones that JavaScript has.
Conditional Statements
The first thing to know are the expressions that evaluate to true/false:
False Values
falseundefinednull0NaN- the empty string (
"") 
True Values
- All other values, including all objects
 
In this sense, it is more similar to languages like
Crather thanJava
Note
There is a non-trivial difference between the object
Booleanand the values oftrueandfalse:
 1
2
3 var b = new Boolean(false);
if (b) // this condition evaluates to true
if (b == true) // this condition evaluates to false
If-Else
This is basically the same across most languages:
1  | if (condition_1) {  | 
Switch
Again, this is the same in languages like Java:
1  | switch (expression) {  | 
The program first looks for a
caseclause with a label matching the value of expression and then transfers control to that clause, executing the associated statements.If no matching label is found, the program looks for the optional
defaultclause:- If a 
defaultclause is found, the program transfers control to that clause, executing the associated statements. - If no 
defaultclause is found, the program resumes execution at the statement following the end ofswitch. 
- If a 
 
Note that:
- Same as Java, the optional
 breakstatement associated with eachcaseclause ensures that the program breaks out ofswitchonce the matched statement is executed.
- If
 breakis omitted, the program continues execution inside theswitchstatement (and will evaluate the nextcase, and so on).
Handling Exceptions
There are some differences between JavaScript and languages like Java:
- Just about any object can be thrown in JavaScript.
- though it is more frequent to throw:
 
 
For Example: Throwing any Object
1  | throw 'Error2'; // String type  | 
For Example: Throwing a Simple Custom Exception
1  | // Create an object type UserException  | 
where:
- in general, it is a good practice to have a 
nameandmessagefield (see [Utilizing Error Objects](#Utilizing Error Objects)) 
Catch and Finally
Since JavaScript is a weakly typed language (as compared to Java), it only makes sense to have at most one catch block:
1  | openMyFile();  | 
Note that:
Same as in languages like Java, using
finallymeans you might “mask the exceptions” thrown in the originaltryblock:
 1
2
3
4
5
6
7
8
9
10
11
12 function f() {
try {
throw 'bogus';
} catch(e) {
console.log('caught inner "bogus"');
throw e; // this throw statement is suspended until
// finally block has completed
} finally {
return false; // OVERWRITES/MASKS the previous "throw"
}
// "return false" is executed now
}where:
- in fact, in this case, you will never be able to throw an exception from the function
 f()
Utilizing Error Objects
In general, two fields are often used:
- the
nameproperty provides the general class ofError(such asDOMExceptionorError) - the 
messagegenerally provides a more succinct message than one would get by converting the error object to a string. 
A simple example would be:
1  | try {  | 
Loops and Iteration
In summary, you have:
forloopsimilar to the Java and C
forloop.1
2
3
4
5for (let i = 0; i < selectObject.options.length; i++) {
if (selectObject.options[i].selected) {
numberSelected++;
}
}where:
letis often used because the variable would be then local scoped
do...whileloopagain, similar to Java
1
2
3do
statement
while (condition);
whileloopwhile (condition) statement <!--59-->
to break:
1
2break;
break [label];
For Example
1  | let x = 0;  | 
Enhanced for Loops
There are “two” enhanced for loops:
for...in- iterates a specified variable over all the enumerable properties of an object
 
for...of- iterates over iterable objects (including
Array,Map,Set,argumentsobject and so on) 
- iterates over iterable objects (including
 
For Example: for...in Loop
1  | function dump_props(obj, obj_name) {  | 
For an object car with properties make and model, result would be:
1  | car.make = Ford  | 
Note: If you want to iterate over an array:
- In most cases, it is better to use a traditional
 forloop with a numeric index when iterating over arrays, because thefor...instatement iterates over user-defined properties in addition to the array elements, if you modify the Array object (such as adding custom properties or methods).
For Example: for...of Loop
1  | const arr = [3, 5, 7];  | 
Functions
Defining Functions
A function definition (also called a function declaration, or function statement) consists of the function keyword, followed by:
- The name of the function.
 - A list of arguments
 - The JavaScript statements that define the function, enclosed in curly brackets, 
{...}. 
Note
- Same as Java and C, JavaScript passes parameters by value. So that
 
- primitive passes by value of the primitive
 - object passes y the value of the address
 
For Example
1  | function functionName(arguement1, arguement2) {  | 
Function Expressions
This basically treats functions as expressions, and you can also pass them around like variables.
A function expression:
- can be anonymous
 - assigned to a variable to pass around
 
For Example: Function Statement
1  | const factorial = function fac(n) { return n < 2 ? 1 : n * fac(n - 1) }  | 
Reminder
In
C, you have the equivalent like this:
 1 const int (*factorial)(int n) = &fac;
For Example: Passing in a Function
1  | function map(f, a) {  | 
Function returns: [0, 1, 8, 125, 1000].
Function Hoisting
Function declaration, like variables, are hoisted.
However:
- function expressions are not hoisted.
 
For Example:
1  | console.log(square(5));  | 
However:
1  | console.log(square) // square is hoisted with an initial value undefined.  | 
Recursion
A function can refer to and call itself. There are three ways for a function to refer to itself:
- The function’s name
 arguments.callee- An in-scope variable that refers to the function
 
For example
1  | var foo = function bar() {  | 
where, within the function body, the following are all equivalent:
bar()arguments.callee()foo()
Closure
Closure describes the property of nested functions such that:
- the inner function full access to all the variables and functions defined inside the outer function (and all other variables and functions that the outer function has access to)
 - the outer function does not have access to the variables and functions defined inside the inner function.
 
As a result
- since the inner function has access to the scope of the outer function, the variables and functions defined in the outer function will live longer than the duration of the outer function execution, if the inner function manages to survive beyond the life of the outer function
 
For Example
1  | var createPet = function(name) {  | 
Variable Hiding
This talks about the phenomena that:
- If an enclosed function defines a variable with the same name as a variable in the outer scope, then there is no way to refer to the variable in the outer scope again.
 
For Example
1  | var createPet = function(name) { // The outer function defines a variable called "name".  | 
Arguments Object
The arguments of a function are maintained in an array-like object.
- it is strictly speaking not an 
Array(see [Rest Parameters](#Rest Parameters)) 
Within a function, you can address the arguments passed to it as arguments[i].
- in a sense, this means 
varargscomes naturally to JavaScript without specification 
For Example:
1  | function easy(){  | 
For Example: Using Arguments Object
1  | function myConcat(separator) {  | 
and calling it:
1  | // returns "red, orange, blue, "  | 
Arrow Functions
Basically, this idea is analogous to the lambda expressions in Java.
One common usage of arrow function is its combination with Array.prototype.map()
- The 
map()method creates a new array populated with the results of calling a provided function on every element in the calling array. 
For Example:
1  | const array1 = [1, 4, 9, 16];  | 
Function Parameters
Starting with ECMAScript 2015, there are two new kinds of parameters:
- default parameters
 - rest parameters
 
Default Parameters
In JavaScript, parameters of functions default to undefined. However, in some situations it might be useful to set a different default value.
For Example:
1  | function multiply(a, b = 1) {  | 
Rest Parameters
This is basically varargs
- in particular, the rest parameters behaves exactly like an 
Array 
For Example:
1  | function multiply(multiplier, ...theArgs) {  | 
Difference between Rest Parameters and
ArgumentObject
- Arguments object includes all arguments passed to the function, whereas rest parameters are those, which are not given another name.
 - The rest parameters are Array instances, whereas arguments object isn’t an array. Array instances can use the following methods:
 map,sort,pop, etc
Predefined Functions
JavaScript has several top-level, built-in functions (for a full list, please visit this link):
- The 
eval()method evaluates JavaScript code represented as a string. - for example, 
eval("2+2")gives4 
- The 
uneval()method creates a string representation of the source code of anObject 
- The 
isNaN()function determines whether a value isNaNor not. Note: coercion inside theisNaNfunction has interesting rules; you may alternatively want to useNumber.isNaN(), as defined in ECMAScript 2015, or you can usetypeofto determine if the value is Not-A-Number. 
- The 
parseFloat()function parses a string argument and returns a floating point number. 
- The 
parseInt()function parses a string argument and returns an integer of the specified radix (the base in mathematical numeral systems). 
- The 
decodeURI()function decodes a Uniform Resource Identifier (URI) previously created byencodeURIor by a similar routine. 
- The 
decodeURIComponent()method decodes a Uniform Resource Identifier (URI) component previously created byencodeURIComponentor by a similar routine. 
- The 
encodeURI()method encodes a Uniform Resource Identifier (URI) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two “surrogate” characters). 
- The 
encodeURIComponent()method encodes a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two “surrogate” characters). 
Prototype and Inheritance
In Java, suppose you want to have something like:
1  | public class Manager extends Employee {  | 
In JavaScript, you need to do:
1  | function Manager() {  | 
Reminder
- remember that constructor and its superclass information of a custom type is stored in the
 <CustomeType>.prototypefield (see [Prototype Chain](#Prototype Chain)).
Prototypes
In short, a prototype of an Object defines what gets inherited. (It is not to be seen as “prototype object of the current object”).
- this means that any functions defined in 
Object.prototypewill get inherited in any other Object, and other functions defined only withObjectwill not be inherited 
As a result
- So
 Object.prototype.toString(),Object.prototype.valueOf(), etc., are available to any object types that inherit fromObject.prototype, including new object instances created from thePerson()constructor.
For Example:
1  | function Person(first, last, age, gender, interests) {  | 
then, compare:
1  | Person.prototype;  | 
and:
1  | Object.prototype;  | 
Note:
- In the above example, the
 constructorautomatically becomes a property of theprototype.- This means that all Objects from
 Personwill haveconstructoravailable
Revisiting create()
In summary, Object.create() lets you create an Object with a custom prototype:
1  | let person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);  | 
then:
1  | person2.__proto__  | 
Using the constructor property
As shown in the example in the Prototypes section above, a constructor property is automatically placed in prototype, so that
- it is available to all instances of the object
 - and all children inheriting from this object
 
For Example:
1  | let person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);  | 
and more interestingly:
1  | let person3 = new person1.constructor('Karen', 'Stephenson', 26, 'female', ['playing drums', 'mountain climbing']);  | 
works as well.
Modifying Prototypes
In summary, I show:
- how to add a method/function to the 
Person‘s prototype, so that all instances of it/children of it can use the function 
For Example:
1  | // adding a function `farewell()` to prototype  | 
then call it with either:
1  | person1.farewell();  | 
where both would output the same.
Note that:
be careful when defining fields using
this. For instance, below would not work:
 1
2 // `this` refers to the global scope
Person.prototype.fullName = this.name.first + ' ' + this.name.last;and only function scope works properly
 1
2
3
4 Person.prototype.farewell = function() {
// this refers to the Object calling the function (function scope)
alert(this.name.first + ' has left the building. Bye for now!');
};
Inheritance with Prototype
In short, to inherit Teacher from another object Person, you need to:
use
Person.call(this, ...paremeters)- this sets up the 
constructorto inherit properties of another object 
- this sets up the 
 use
Teacher.prototype = Object.create(Person.prototype)- this sets up the 
prototypefield of theTeacherobject - however, this also sets the 
prototype.constructortoPerson(might cause further inheritance issues) 
- this sets up the 
 use
Object.defineProperty()to reset the constructor toTeacher()- so that now 
prototype.constructorwill beTeacher, and inheriting fromTeacherwould lead to the correct constructor being inherited 
- so that now 
 
Recall that:
the
Person.prototypewould basically have the following content:
 1
2
3 farewell: ƒ ()
constructor: ƒ Person(first, last, age, gender, interests)
__proto__: Object
For Example:
Consider the same Person object we had before:
1  | function Person(first, last, age, gender, interests) {  | 
- to create another object 
Teacherthat inherits its fields/properties: 
1  | function Teacher(first, last, age, gender, interests, subject) {  | 
- and then:
 
1  | Teacher.prototype = Object.create(Person.prototype);  | 
where:
- In this case we are using it to create a new object and make it the value of 
Teacher.prototype. 
- Finally, we reset the 
prototype.constructorto make sure future correct behavior for inheriting fromTeacher: 
1  | Object.defineProperty(Teacher.prototype, 'constructor', {  | 
Inheritance with Class
This is applicable since ECMAScript 2015.
In short, this basically allows syntaxes like Java/C++.
For Example:
1  | class Person {  | 
instead of the function constructor and prototype definitions.
Additionally, inheritance becomes:
1  | class Teacher extends Person {  | 
Getters and Setters
In both prototype and class definitions, the idea is basically the same:
- use 
get <property>()for getters in a class - use 
set <property>()for setters 
For Example: Class Based Getter and Setter
1  | class Teacher extends Person {  | 
For Example: Prototype Based Getter and Setter
1  | Object.defineProperties(Teacher.prototype, {  | 
Dynamic Client Side Programming
This section talks about the building blocks of programming a dynamic website/application.
Working with JSON
JavaScript Object Notation (JSON) is a standard text-based format for representing structured data based on JavaScript object syntax.
- therefore, all you need to do is to parse the JSON string using 
JSON.parse() 
JavaScript provides a global JSON object that has methods available for converting between the two.
Array as JSON
Basically arrays are formatted using the [] symbol.
For Example:
1  | let heroes = JSON.parse(`[  | 
JSON Structure/Object
In general, an object in JSON uses the format:
1  | {  | 
For Example
1  | '{  | 
Using XMLHttpRequest
In short, you can obtain data with with JavaScript using a XMLHttpRequest to a backend server.
The API called
XMLHttpRequest(often called XHR). This is a very useful JavaScript object that allows us to make network requests to retrieve resources from a server via JavaScript (e.g. images, text, JSON, even HTML snippets), meaning that we can update small sections of content without having to reload the entire page.
To do this, you usually need to:
- prepare the 
requestURL - create a 
new XMLHttpRequest() - open the request and set the request methods and request URL
 - set the expected response type
 - send the request
 - format the response in the 
request.responseinto your HTML- here you will use the 
onloadfunction 
 - here you will use the 
 
For Example
For step 1-5:
1  | let requestURL =  | 
For step 6:
1  | request.onload = function() {  | 
where:
- The 
XMLHttpRequest.onloadis the function called when anXMLHttpRequesttransaction completes successfully. 
Lastly, to format the data into the web page:
1  | <body>  | 
and to populate the header and section:
1  | const header = document.querySelector('header');  | 
Converting between Objects and Text
The above section worked with a piece of JSON data directly. However, sometimes data sent are in the forms of a String, or that you need to send data across in String. As a result, you need to convert between a String to a JS Object.
To do this, use the functions of the JSON object:
parse(): Accepts a JSON string as a parameter, and returns the corresponding JavaScript object.stringify(): Accepts an object as a parameter, and returns the equivalent JSON string.
For Example:
If instead of JSON, you receive text:
1  | request.open('GET', requestURL);  | 
and to use stringify()
1  | let myObj = { name: "Chris", age: 38 };  | 
Asynchronous JavaScript
This section assumes some prior knowledge of threading and blocking, so that you need to know:
- a browser blocks user’s inputs when the (JS) application has not been computed/rendered
 - programs by default are single threaded (main thread)
 
Therefore, the solution is avoid blocking is to:
- do some expensive task in another thread:
 
1  | Main thread: Task A --> Task C  | 
- use asynchronous programming with a 
Promise 
1  | Main thread: Task A Task B  | 
For Example: Simple Asynchronous JavaScript
Consider the case when you are downloading an image, and then need to do something (e.g. apply a filter) to that image:
1  | let response = fetch('myImage.png'); // fetch is asynchronous  | 
where:
- because 
fetchisasync, it immediately goes on the next line of code without the promise that the download has finished.- as a result, the second line will throw an error if the data isn’t ready
 
 
Async Callbacks
Reminder: Callback functions
Callback functions are just functions passed in as an argument into another function. When the background code finishes running, it calls the callback function to let you know the work is done, or to let you know that something of interest has happened.
for example:
 1
2
3
4
5
6
7 btn.addEventListener('click', () => {
alert('You clicked me!');
let pElem = document.createElement('p');
pElem.textContent = 'This is a newly-added paragraph.';
document.body.appendChild(pElem);
});where:
'click'is the first argument, specifying the type of event thatbtnto listen for- the second argument is the callback function, so that it is invoked after the event is fired
 
A more complete and relevant example would be:
1  | function loadAsset(url, type, callback) {  | 
where:
callbackargument in theloadAsset()serves as a callback function that is waiting on the XHR call to finish downloading the resource (using theonloadevent handler) before it passes it to the callback.
Promises
Promises are the new style of async code that you’ll see used in modern Web APIs. A good example is the fetch() API, which is basically like a modern, more efficient version of XMLHttpRequest.
In short, a Promise is:
it’s the browser’s way of saying “I promise to get back to you with the answer as soon as I can“
technically, it’s an object representing the completion or failure of the async operation (i.e. it is on its way, but it could succeed or fail)
For Example: Using fetch
1  | fetch('products.json').then(function(response) { // the first promise is the response  | 
where:
fetch()taking a single parameter — the URL of a resource you want to fetch from the network — and returning apromise
then, after the async fetch comes back with result, you have:
- Two 
then()blocks. Both contain a callback function that will run if the previous operation is successful, and each callback receives as input the result of the previous successful operation, so you can go forward and do something else to it.- In fact, each 
.then()block returns another promise, meaning that you can chain multiple.then()blocks onto each other, so multiple asynchronous operations can be made to run in order, one after another. 
 - In fact, each 
 - The 
catch()block at the end runs if any of the.then()blocks fail- in a similar way to synchronous 
try...catchblocks, an error object is made available inside thecatch(), which can be used to report the kind of error that has occurred. Note however that synchronoustry...catchwon’t work with promises, although it will work with async/await, as you’ll learn later on. 
 - in a similar way to synchronous 
 
In essence:
Promises are essentially a returned object to which you attach callback functions (with.then()), rather than having to pass callbacks into a function.
Promise.all
For the code before, we are just waiting for a single promise, and then deal with it asynchronously with .then(). But what if you want to run some code only after a whole bunch of promises have all fulfilled?
To do this, you can use the Promise.all() static method:
1  | Promise.all([a, b, c]).then(values => {  | 
where:
- the 
.then()block runs only after all three Promisesa,b,creturned. - the returned 
valueswill be an array of three Promises, in the order of[resultA, resultB, resultC] 
For Example:
Below will send three requests, and render the webpage only when all three request’s data have been received.
Step 1, send the three requests async:
1  | let coffee = fetchAndDecode('coffee.jpg', 'blob');  | 
Step 2: wait for all three Promises async, and then render the page:
1  | Promise.all([coffee, tea, description]).then(values => {  | 
where:
- basically now 
values[0]will be the result fromcoffeerequest,values[1]will be fromtearequest, andvalues[2]will be fromdescriptionrequest 
finally for Promises
In short, this is the same as the try...catch...finally logic in languages like Java.
- the 
.finally()method can be chained onto the end of your regular promise chain, and is guaranteed to be run in the end 
For Example:
1  | function fetchAndDecode(url, type) {  | 
where:
fetch attempt for "${url}" finished.will be printed in console no matter the requests failed or succeeded.
Creating Own Promises
In short, we know that a promise “does two things”:
- resolve/fulfill the task
- the underneath 
resolve()function 
 - the underneath 
 - failed to resolve/fulfill the task
- the underneath 
reject()function 
 - the underneath 
 
Therefore, this is the common usage of a Promise() constructor:
1  | new Promise(resolveFunction, rejectFunction);  | 
so that you will have code like this:
1  | const myFirstPromise = new Promise((resolve, reject) => {  | 
For Example:
1  | function timeoutPromise(message, interval) {  | 
where:
- if successful, the data Promise will be a string of
"Success"(in analogy of what we have done withfetch, the success result is a theresponse) - if failed, the error will be the string error message inside the 
reject()clause. 
For Example:Mimicking fetch
1  | function myAsyncFunction(url) {  | 
where:
- this basically mimics what happens under a 
fetchAPI 
Introduction to Events
In the case of the Web, events are fired inside the browser window, and tend to be attached to a specific item that resides in it — this might be a single element, set of elements, the HTML document loaded in the current tab, or the entire browser window.
There are many different types of events that can occur. For example:
- The user selects a certain element or hovers the cursor over a certain element.
 - The user hits a key on the keyboard.
 - The user resizes or closes the browser window.
 - A web page finishes loading.
 - A form is submitted.
 - A video is played, paused, or finishes.
 - An error occurs.
 
There are even more in the MDN Event reference.
Now, to interact with the events, you typically use the event handler.
- Each available event has an event handler, which is a  block of code (usually a JavaScript function that you as a programmer  create) that runs when the event fires. 
- When such a block of code is defined to run in response to an event, we say we are registering an event handler.
 
 
Note:
- Event handlers are sometimes called event listeners — they are pretty much interchangeable for our purposes, although strictly speaking: the listener listens out for the event happening, and the handler is the code that is run in response to it happening.
 
For Example: A simple Example
First, in the html, there is a button element:
1  | <button>Change color</button>  | 
then, we would like to interact with the click event of the button:
1  | const btn = document.querySelector('button');  | 
where:
- first we store a reference to the button inside a constant called 
btn, using theDocument.querySelector()function - then we defined a function 
random()that returns a number - finally, we have the event handler: the object 
buttonhas a number of events that can fire on it, and therefore, event handlers available.- Here, we are listening for the 
clickevent firing, by setting theonclickevent handler property to equal an anonymous function containing code that generates a random RGB color and sets the<body>background-colorequal to it. - Therefore, the event handler code runs/handles whenever the 
clickevent fires on the<button>element, that is, whenever a user selects it. 
 - Here, we are listening for the 
 
Event Handler Properties
In short, those are properties that exists to contain the event handler code.
An example would be the above code:
1  | const btn = document.querySelector('button');  | 
where:
- The 
onclickproperty would contain the code for handling the eventclick 
In fact, some other common event handler properties include:
btn.onfocusandbtn.onblur- The color changes when the button is focused (selected) and unfocused (unselected);
 
btn.ondblclick- the color changes when the button is double clicked
 
window.onkeypress,window.onkeydown,window.onkeyup- The color changes when a key is pressed on the keyboard.
 - note that we register it on the window object, which represents the entire browser window.
 
btn.onmouseoverandbtn.onmouseout- The color changes when the mouse pointer hovers over the button, or when the pointer moves off the button, respectively.
 
Note that:
- Some events are general and available nearly anywhere (e.g. an
 onclickhandler can be registered on nearly any element), whereas some are more specific and only useful in certain situations (e.g. it makes sense to use onplay only on specific elements, such asvideo).
For Example: Using foreach with handler property
Sometimes, when you want to set a number of buttons on the page to simultaneously, you can do:
- select all the button elements
 
1  | const buttons = document.querySelectorAll('button');  | 
- Iterate through the array of buttons and assign them:
 
1  | // either  | 
where:
- The 
forEach()method of theNodeListinterface calls the callback given in parameter once for each value pair in the list 
Using addEventListener()
Instead of setting the event handler/listener inside the property, you can use the addEventListener() directly to the object:
1  | target.addEventListener(type, listener [, options]);  | 
For instance, converting the previous example into addEventListener() code, you will have:
1  | const btn = document.querySelector('button');  | 
where:
- Inside the 
addEventListener()function, there are two parameters:- the name of the event we want to this 
target=btnto listen to - the code that comprises the handler function we want to run in handle it.
 
 - the name of the event we want to this 
 
There are some advantages of this over the mechanism of using property:
- there is a counterpart function, 
removeEventListener()which removes a previously added listener. - you can perform various functions at the same time with 
addEventListener() 
For Example: Using addEventListener and removeEventListener
To register multiple handlers to execute simultaneously when an event is fired:
1  | myElement.addEventListener('click', functionA);  | 
then, to remove one of the handlers, use:
1  | myElement.removeEventListener('click', functionA);  | 
The Event Object
The event object is automatically passed to event handlers to provide extra features and information.
- one useful property of the 
eventobject is theevent.target- a reference to the element the event occurred upon 
For Example: Changing the color of the button itself
To get the button, you can use the e.target instead of the btn Object.
1  | function bgChange(e) {  | 
where:
- notice that the handler function now takes the argument 
e/evt/eventobject, which is automatically passed in when an event occurs 
Most event handlers you’ll encounter have a standard set of properties and functions (methods) available on the event object; see the
Eventobject reference for a full list.
Preventing Default Behavior
In short, this uses the function preventDefault() of the event Object
- this is useful when, for example, a user has filled the form incompletely, and you want to prevent the action of submitting the incomplete form.
 
For Example:
First, you have the form html:
1  | <form>  | 
then, you need to alter the event object so that its default action of submitting (for a form) is prevented:
1  | const form = document.querySelector('form');  | 
Event Capturing and Bubbling
This talks about the phenomena that, since some elements have a layered/nested structure, (e.g. the video element below is inside the div), clicking the video will have also clicked the div:

(source: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events)
As a result, some unwanted action might happen. If you want to only trigger the onclick of the video, then you first need to understand the bubbling and capturing phase:
In the capturing phase:
- The browser checks to see if the element’s outer-most ancestor (
html) has anonclickevent handler registered on it for the capturing phase, and runs it if so. - Then it moves on to the next element inside 
<html>and does the same thing, then the next one, and so on until it reaches the element that was actually selected. 
In the bubbling phase, the exact opposite occurs:
- The browser checks to see if the element selected (innermost) has an 
onclickevent handler registered on it for the bubbling phase, and runs it if so. - Then it moves on to the next immediate ancestor element and does the same thing, then the next one, and so on until it reaches the 
<html>element. 
In modern browsers, by default, all event handlers are registered for the bubbling phase.
- this means that it is the
 Eventobject that bubbles up from handlersIf you really want to register an event in the capturing phase instead, you can do so by registering your handler using
addEventListener(), and setting the optional third property totrue.
Therefore, the solution here is to stop the bubbling propagation with the stopPropagation(), so that when the innermost video is clicked, the outer div and so on are not triggered.
- technically: the standard 
Eventobject has a function available on it calledstopPropagation()which, when invoked on a handler’s event object, makes it so that first handler is run but the event doesn’t bubble any further up the chain, so no more handlers will be run. 
In code, you will need:
1  | // `videoBox` is the outer `div` element  | 
Event Delegation
This talks about utilizing the bubbling propagation to gain information on its immediate child.
- since the 
Eventobject gets bubbled up, we can check the value of theevent.targetto know the child value 
Consider the case where you have a list of items:
1  | <ul id="parent-list">  | 
then you want to have an event listener for each item if it gets clicked. The most efficient way is to utilize the bubbling and the event object:
1  | // Get the element, add a click listener...  | 
where:
- the 
Eventobject is bubbled up, soEvent.targetcontains the innermost clicked information 
Introduction to APIs
This section assumes some prior knowledge/experience of using APIs. So that you know what APIs are, and have used them at least for once.
APIs in Client-Side JavaScript
Client-side APIs include:
- Browser APIs
- APIs built into your web browser and are able to expose data from the browser and surrounding computer environment and do useful complex things with it.
 - For example, the Web Audio API provides JavaScript constructs for manipulating audio in the browser — taking an audio track, altering its volume, applying effects to it, etc.
 
 - Third-party APIs
- APIs not built into the browser by default, and you generally have to retrieve their code and information from somewhere on the Web.
 - For example, the Twitter API allows you to do things like displaying your latest tweets on your website.
 
 
And importantly, the distinction between JavaScript Library and JavaScript Frameworks
- JavaScript libraries — Usually one or more JavaScript files containing custom functions that you can attach to your web page to speed up or enable writing  common functionality. 
- Examples include jQuery, Mootools and React.
 
 - JavaScript frameworks — The next step up from libraries, JavaScript frameworks (e.g. Angular and Ember) tend to be packages of HTML, CSS,  JavaScript, and other technologies that you install and then use to write an entire web application from scratch. 
- The key difference between a library and a framework is “Inversion of Control”. When calling a method from a library, the developer is in control. With a framework, the control is inverted: the framework calls the developer’s code. (i.e. you are just “configuring the framework’s behavior”)
 
 
Common APIs to Know
APIs for manipulating documents loaded into the browser.
- The most obvious example is the DOM (Document Object Model) API, which allows you to manipulate HTML and CSS — creating, removing and changing HTML, dynamically applying new styles to your page, etc
 - see more in [Manipulating documents](#Manipulating documents)
 
APIs that fetch data from the server to update small sections of a webpage on their own are very commonly used.
- Some common examples include 
XMLHttpRequestand the Fetch API. You may also come across the term Ajax, which describes this technique. - see more in [Fetching data from the server](#Fetching data from the server)
 
- Some common examples include 
 APIs for drawing and manipulating graphics are now widely supported in browsers — the most popular ones are Canvas and WebGL, which allow you to programmatically update the pixel data contained in an HTML
canvaselement to create 2D and 3D scenes.Audio and Video APIs like
HTMLMediaElement, the Web Audio API, and WebRTC allow you to do really interesting things with multimedia- For example, creating custom UI controls for playing audio and video, displaying text tracks like captions and subtitles along with your videos
 
Device APIs are basically APIs for manipulating and retrieving data from modern device hardware in a way that is useful for web apps.
- Examples include telling the user that a useful update is available on a web app via system notifications
 
Client-side storage APIs are becoming a lot more widespread in web browsers — the ability to store data on the client-side is very useful.
- There are a number of options available, e.g. simple name/value storage with the Web Storage API, and more complex tabular data storage with the IndexedDB API.
 
In terms of Third-party APIs, some common ones are:
The Twitter API, which allows you to do things like displaying your latest tweets on your website.
Map APIs like Mapquest and the Google Maps API allows you to do all sorts of things with maps on your web pages.
The Facebook suite of APIs enables you to use various parts of the Facebook ecosystem to benefit your app, for example by providing app login using Facebook login, accepting in-app payments, rolling out targeted ad campaigns, etc.
etc.
Entry Points of Common APIs
When using an API, you should make sure you know where the entry point is for the API.
In The Web Audio API, this is pretty simple — it is the
AudioContextobject, which needs to be used to do any audio manipulation whatsoever.The Document Object Model (DOM) API also has a simple entry point — its features tend to be found hanging off the
Documentobject, or an instance of an HTML element that you want to affect in some wayThe Canvas API also relies on getting a context object to use to manipulate things, although in this case, it’s a graphical context rather than an audio context.
- Its context object is created by getting a reference to the 
canvaselement you want to draw on, and then calling itsHTMLCanvasElement.getContext()method 
- Its context object is created by getting a reference to the 
 
For Example: Using Web Audio API
The entry point is usually the AutioContext Object:
1  | const AudioContext = window.AudioContext || window.webkitAudioContext;  | 
and then you could add functions such as:
1  | const audioElement = document.querySelector('audio');  | 
For Example: Using DOM APIs
1  | const em = document.createElement('em'); // create a new em element  | 
For Example: Canvas APIs
To get the entry point for a Canvas, you usually use the context of the canvas object:
1  | const canvas = document.querySelector('canvas');  | 
then to put some custom shapes into the canvas, you can use the context object:
1  | Ball.prototype.draw = function() {  |