as expressions are phrases
STATEMENTS
are sentences or commands
terminated with semicolons
which are executed to make something happen
JavaScript programs are
a sequence of statements
which an interpreter executes
one after another in the same order they were written
another way to make things happen
is to alter the default order of execution
JavaScript
has a number of statements or control structures
that help at this
conditional
are statements like if & switch that make the interpreter execute or skip
other statements depending on the value of an expression
loops
are statements like while & for that execute other statements repetitively
jumps
are statements like break / return / throw that cause the interpreter to
jump to another part of the program
Statement | Syntax | Purpose |
break | break [label]; | Exit from the innermost loop or switch or from named enclosing statement |
case | case expression: | Label a statement within a switch |
continue | continue [label]; | Begin next iteration of the innermost loop or the named loop |
debugger | debugger; | Debugger breakpoint |
default | default: | Label the default statement within a switch |
do/while | do statement while (expression); | An alternative to the while loop |
empty | ; | Do nothing |
for | for (init; test; incr) statement | An easy-to-use loop |
for/in | for (var in object) statement | Enumerate the properties of object |
function | function fnName([param[,...]]) { body } | Declare a named function |
if/else | if (expr) statement1 [else statement2] | Execute statement1 or statement2 |
label | label: statement | Give statement the name label |
return | return [expression]; | Return a value from a function |
switch | switch (expression) { statements } | Multiway branch to case or default: labels |
throw | throw expression; | Throw an exception |
the next table summarizes all JavaScript statements
listing their syntax & purpose
Statement | Syntax | Purpose |
try | try { statements } [catch { handler statements }] [finally { cleanup statements }] |
Handle exceptions |
use strict | "use strict"; | Apply strict mode restrictions to script or function |
const, let | const name [ = expr] [ ,... ]; | Declare and initialize one or more variables or constants |
while | while (expression) statement | A basic loop construct |
with | with (object) statement | Extend the scope chain (forbidden in strict mode) |
the simplest JavaScript statements are
expressions & that have side effects
assignment / increment & decrement / delete
or
function calls
assignment
= / += / -= / *= / /= / %= / <<= / >>= / >>>= / &= / |= / ^=
title = language + '- The Basics';
count += 15;
increment & decrement
++ / --
count++;
they have the side effect of changing a variable value
as if an assignment has been performed
delete
delete
delete obj.prop;
has the side effect of deleting an object property
functions calls
confirm(message);
a function call can also be a part of a larger expression
or an assignment statement
are another major category of expression statements
var confirmed = confirm(message);
if (confirmed) {
// do something if user has clicked on OK alert button
} else {
// do something else
}
a block statement combines multiple statements
into a single compound statement
which is just a sequence of statements enclosed in curly braces
{
title = 'JavaScript - The Basics';
subtitle = 'Statements';
console.log(title + ' ' + subtitle);
}
statement block
as it can be seen
the block statement does not end with a semicolon
but statements within the block end in semicolons
the lines inside the block are indented
which is optional but it makes code easier to read
the empty statement is the opposite of the statement block
&
allows to include no statement where one is expected
empty statement
;
interpreter takes no action when it executes an empty statement
which is useful in creating a loop with an empty body
var i, arr = [1, 2, 3, 4, 5];
for (i = 0; i < arr.length; arr[i++] = i * 0.5) ;
console.log(arr); //=> [0.5, 1, 1.5, 2, 2.5]
var, let, const & function
are declaration statements
they define identifiers that can be used
elsewhere in a JavaScript program
&
assign values to those identifiers
var
var statement declares a variable or variables
var name_1 [ = value_1] [ ,..., name_n [= value_n]]
var keyword is followed by a comma-separated
list of variables to be declared
each variable in the list may optionally have
an initializer expression that specifies its initial value
var i; // a simple variable
var i = 0; // a simple initialized variable
var i, j; // a list of variables
var i = 1, j = 15; // a list of initialized variables
var i = 1, // a list of initialized variables
j = 15; // declared on separate lines
let
let declares a block scope local variable, optionally initializing it to a value.
let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];
let keyword is followed by a comma-separated
list of variables to be declared
each variable in the list may optionally have
an initializer expression that specifies its initial value
let i; // a simple variable
let i = 0; // a simple initialized variable
let i, j; // a list of variables
let i = 1, j = 15; // a list of initialized variables
let i = 1, // a list of initialized variables
j = 15; // declared on separate lines
const
const declaration creates a read-only reference to a value
const name1 = value1 [, name2 = value2 [, ... [, nameN = valueN]]];
const keyword is followed by a comma-separated
list of variables to be declared
const i; // will throw an error
const i = 0; // a simple initialized variable
const i, j; // will trhow an error
const i = 1, j = 15; // a list of initialized variables
const i = 1, // a list of initialized variables
j = 15; // declared on separate lines
unlike var or let, constants declarations must assign a value
function
function keyword is used to define functions
function fnName([arg1 [, arg2 [..., argN]]]) {
statements
}
fnName is an identifier
which gives a name to the function that has been declared
arg1... argN are arguments passed to the function
statements are any number of statements contained
within curly braces
function sum(x, y) {
return x + y;
}
function* (ES2015)
function* declaration (function keyword followed by an asterisk) defines a generator function, which returns a Generator object
... to be coninuted
function declaration statements differ from function definition expressions in that they include a function name
both create a new function object
BUT
the function declaration statement also declares the function name as a variable & assigns the function object to it
AND
function declarations are HOISTED as of expressions which are not
conditional statements
are used to execute or skip other statements
depending on the value of a specified expression
they are the decision points of any code
is the fundamental control statement that allows JavaScript to make
decisions or to execute statements conditionally
it has two forms
if (expression)
statement
if
expression is evaluated & if the value is truthy
statement is executed
otherwise if is falsy then it is not executed
var truthy = 1,
falsy = 0;
if (truthy)
console.log(truthy + ' is `truthy` value');
if (falsy)
console.log('This will not be printed, guess why?');
&
the second form
if (expression)
statementOne
else
statementTwo
which introduces an else clause
that is executed when expression is false
var falsy = 0;
if (falsy)
console.log('This will not be printed, guess why?');
else
console.log('Because ' + falsy + ' is a `falsy value`');
the if syntax is very clear & simple
however it is important to know that
parentheses around the expression are required
&
JavaScript requires a single statement
after the if keyword & the expression
BUT
a statement block can be used
to combine multiple statements into a single one
var falsy = 0;
if (falsy) {
console.log('This will not be printed, guess why?');
} else {
console.log('Because ' + falsy + ' is a `falsy value`');
}
it is also recommended to always use a
statement block to ensure that the interpreter
always follows the correct path
var x = 1, y = 1, z = 2 ;
if (x === y)
if (x === z)
console.log('x is equal to z');
else
console.log('x is not equal to y');
//=> "x is not equal to y"
var x = 1, y = 1, z = 2 ;
if (x === y) {
if (y === z) { // y is not equal to z
console.log('y is equal to z'); // that's why this is not printed
}
} else { // x is equal to y
console.log('x is not equal to y'); // that's why this is not printed
}
if / else statement evaluates an expression
and then executes one of two pieces of code
BUT
when one of many pieces of code have to be executed
else if statement becomes really handy
else if
var i = 0;
if (i === 0) {
console.log('`i` is zero');
} else if (i === 1) {
console.log('`i` is one');
} else if (i === 2) {
console.log('`i` is two');
} else {
console.log('No one knows the value of `i`');
}
if statement changes the flow of the program
by making the interpreter to follow a certain path
else if statement helped by adding multiple clauses to if
to perform a multiway branch
BUT
even if it's handy it is not always the best solution
when all the branches depend on the value of the same expression
switch
this is why switch statement is used to handle
such situtations
it's syntax looks as follows
switch (expression) {
case valueOne:
statementForCaseOne
[break;]
case valueTwo:
statementForCaseTwo
[break;]
...
case valueN:
statementForCaseN
[break;]
default:
defaultStatement
[break;]
}
var i = 0;
switch (i) {
case 0:
console.log('`i` is zero');
break;
case 1:
console.log('`i` is one');
break;
case 2:
console.log('`i` is two');
break;
default:
console.log('No one knows the value of `i`');
break;
}
rewriting the if / else if / else example with switch
switch works by simply computing the value of expression i
and then looks for a case label whose expression evaluates to the same value
if it finds one it start executing the the block of code
if it doesn't it looks for the default label
if there's no default it skips the entire block of code
looping statements
are used to execute other statements repetitively
as conditional statements build a path through a source code
looping statements
bend that path upon itself to repeat portions of code
JavaScript has four looping statements
while / do while / for / for in
while statement is JavaScript’s basic loop
which has the following syntax
while (expression)
statement
while
expression is evaluated
if the value is falsy then the interpreter skips over the statement
otherwise
if the expression is truthy it executes the statement & repeats
by jumping back to the top of the loop
where it starts again by re-evaluating the expression
var count = 0;
while (count <= 15) {
console.log(count);
count++;
}
//=> it will print numbers from 0 to 15 then it stops
do/while loop statement is like while
except that the expression is tested at the bottom
meaning that the body of the loop is executed at least once
do
statement
while (expression);
do/while
var test = false;
do {
console.log(test);
} while (test);
//=> it will print `false` and then it stops
there are also syntactic differences between do/while & while
do/while requires both do & while keywords
do/while always ends with a semicolon
for statement is a looping construct that is often
more convenient than the while statement
because it encodes the loop counter variable
initialization / test & increment
as expressions that are a part of the loop syntax
for (initialize; test; increment)
statement
for
the three expressions are separated by semicolons
&
are responsible for
initializing / testing & incrementing
the loop variable
initialize expression is evaluated once before the loop begins
test expression is evaluated before each iteration
and controls whether the body of the loop is executed
then the increment expression is evaluated
for (var count = 0; count <= 15; count++)
console.log(count);
//=> it will print numbers from 0 to 15 then it stops
for/in statement uses the for keyword
BUT
is different than the regular for loop
for (variable in object)
statement
for/in
variable is an identifier or a var statement that declares a variable
object is an expression that evaluates to an object
var obj = { title: 'JavaScript - The Basics', chapter: 'Statements'};
for (var prop in obj) {
console.log(prop + ': ' + obj[prop]);
}
// It prints:
// title: JavaScript - The Basics
// chapter: Statements
the JavaScript interpreter first evaluates the object expression
if it evaluates to null or undefined - the interpreter skips the loop
if it evaluates to a primitive value - that value is converted to its wrapper object
otherwise - the expression is already an object
the interpreter now executes the body of the loop
once for each enumerable property of the object
BUT
before each iteration it evaluates the variable expression
and assigns the name of the property to it
note:
new ES2015 syntax: for ... of
jump statements
are statements that make the JavaScript interpreter
to jump to a new location in the source code
in JavaScript any statement can be labeled
by preceding it with an identifier and a colon
which gives a name to that statement
name that can be used to refer to it elsewhere in the program
identifier: statement
labeled statements
labeled statements can only be used with break and continue statements
inside a loop to exit or to jump to the top of that loop
var i, j;
console.log('| i | j |');
outer: for (i = 0; i <= 2; i++) {
inner: for (j = 0; j <= 2; j++) {
if (i === 1 && j === 1) {
continue outer;
}
console.log('| ' + i + ' | ' + j + ' |');
}
}
// Prints
// | i | j |
// | 0 | 0 |
// | 0 | 1 |
// | 0 | 2 |
// | 1 | 0 |
// | 2 | 0 |
// | 2 | 1 |
// | 2 | 2 |
identifier used to label a statement
can be any legal JavaScript identifier which is not a reserved word
break statement causes the innermost
enclosing loop or switch statement to exit immediately
it has a simple syntax
break;
break
it is allowed to use a label statement after the break keyword
which causes a jump to the end of the enclosing statement that has the specified label
break labelname;
for (var i = 0; i < 15; i++) {
if (i === 7) { break; }
console.log(i);
}
// Prints numbers from 0 to 6 and then exits the loop
continue statement is similar to break
but instead of exiting the loop
it restarts the loop at the next iteration
continue;
continue
as for the break statement it can be used with a label statement
continue labelname;
for (var i = 0; i < 15; i++) {
if (i === 7) { continue; }
console.log(i);
}
// Prints numbers from 0 to 14 excluding 7
when continue statement is executed
the current iteration of the enclosing loop is terminated
and the next iteration begins
that means different things for different types of loops
while
the expression is tested again and if it’s true the loop body is executed starting from the top
do/while
execution skips to the bottom where the loop condition is tested before restarting the loop
for
the increment expression is evaluated & the test expression is tested again
to determine if another iteration should be done
for/in
the loop starts over with the next property name being assigned to the specified variable
return statement ends a function execution
and specifies the value to be returned to the function caller
return expression;
return
function sum(x, y) {
return x + y;
}
it may appear only within the body of a function
a function with no return statement
executes all statements within its body and then returns to its caller
in this case the value of the invocation expression will be undefined
throw statement throws a user defined exception
where an exception means that some sort of exceptional
condition or error has occurred
in JavaScript exceptions are thrown whenever
a runtime error occurs & whenever the program explicitly throws one
exceptions are caught with the try/catch/finally statement
throw
throw statement has the following syntax
throw expression;
expression value can have any type
it might be a number that represents an error code
or a string representing an error message
throw 404; //=> 404
throw 'This is cool!'; //=> "This is cool!"
throw new Error('This is a cool error message!'); //=> Error: This is a cool error message!
as it can be seen above the Error class can be used as well
the JavaScript interpreter uses this class
and its subclasses internally to throw errors
when an exception is thrown JavaScript interpreter
immediately stops normal program execution
and jumps to the nearest exception handler
if the block of code in which the exception was thrown doesn't have an exception handler
the interpreter checks the next highest enclosing block of code until a handler is found
var bool = true, arr = [1, 2, 3, {}], i, elem, type;
if (bool) {
if (arr.length) {
for (i = 0; i < arr.length; i++) {
elem = arr[i];
type = typeof elem;
if (type !== 'number') { throw new Error(type + ' is not a number'); }
console.log(elem + ' is a number')
}
}
try {
// nothing here we just catch the above throw statement
} catch (err) {
console.log(err.message);
}
}
exceptions propagate up through the lexical structure
of JavaScript methods & up the call stack
if no exception handler is ever found
the exception is treated as an error and is reported to the user
try/catch/finally statement is JavaScript’s exception handling mechanism
it provides a way to handle errors that may occur
in a given block of code while still running code
try/catch/finally
try {
try_statements
}
[catch (exception_var) {
catch_statements
}]
[finally {
finally_statements
}]
try
defines the block of code whose exceptions are to be handled
catch
clause is a block of statements that are invoked
when an exception occurs anywhere within the try block
finally
block contains cleanup code that is guaranteed to be executed
regardless of what happens in the try block
catch and finally are optional
BUT
try must be accompanied by at least one of these blocks
yield is used to pause and resume a generator function
yield (ES2015)
it can be used only with generator functions
function* simpleIterator(arr) {
for (item in arr) {
yield item;
}
}
const arr = [1,2,3,4];
const it = simpleIterator(arr);
console.log(it.next()); // => Object {value: "0", done: false}
with statement is used to temporarily extend the scope chain
it's syntax looks as follows
with
with (object)
statement;
in other words with statement was intended to provide a shorthand
when accessing the properties of an object
by adding object to the front of the scope chain
keep in mind that it works just for reading properties
not for creating new ones
a common use for the with statement
is to make it easier to work with deeply nested object hierarchies
var data = {
course: {
title: 'JavaScript - The Basics',
chapters: [{
table_of_contents: {
introduction: {
title: 'Introduction',
pages: {
count: 10,
start_page: 1
}
}
}
}]
}
};
with (data.course.chapters[0].table_of_contents) {
console.log(
introduction.title,
introduction.pages.count,
introduction.pages.start_page
);
}
//=> Introduction 10 1
debugger statement suspends execution
and performs debugging actions if a debugger program is available and running
otherwise it has no effect
in the real word it acts like a breakpoint
that stops the execution of a JavaScript program
it can be used to
inspect variables' values
examine the call stack
single-step code
its syntax is simple
debugger
debugger;
"use strict" is more of a directive than a statement
that was introduced in ECMAScript5 specification
its role is to indicate that code that follows is strict code
"use strict"
"use strict";
'use strict';
strict code is executed in strict mode
which is a subset of the language that fixes a few important language deficiencies
and provides stronger error checking and increased security
differences between
strict mode and non-strict mode
are the following
strict mode | non-strict mode |
with statement is not allowed | - |
all variables must be declared | implicitly declared global variable added as a new property to the global object |
functions invoked as functions (rather than as methods) have a this value of undefined | functions invoked as functions are always passed the global object as their this value |
when a function is invoked with call() or apply(), the this value is exactly the value passed as the first argument to call() or apply() | null and undefined values are replaced with the global object and non-object values are converted to objects |
assignments to nonwritable properties and attempts to create new properties on nonextensible objects throw a TypeError | these attempts fail silently |
code passed to eval() cannot declare variables or define functions in the caller’s scope as it can in non-strict mode. Instead, variable and function definitions live in a new scope created for the eval(). This scope is discarded when the eval() returns | - |
strict mode | non-strict mode |
the arguments object in a function holds a static copy of the values passed to the function | the arguments object has "magical" behavior in which elements of the array and named function parameters both refer to the same value |
a SyntaxError is thrown if the delete operator is followed by an unqualified identifier such as a variable, function, or function parameter | such a delete expression does nothing and evaluates to false |
an attempt to delete a nonconfigurable property throws a TypeError | the attempt fails and the delete expression evaluates to false |
it is a syntax error for an object literal to define two or more properties by the same name | no error occurs |
it is a syntax error for a function declaration to have two or more parameters with the same name | no error occurs |
octal integer literals (beginning with a 0 that is not followed by an x) are not allowed | some implementations allow octal literals |
the identifiers eval and arguments are treated like keywords and it is not allowed to change their value | - |
the ability to examine the call stack is restricted | - |