Control Statements
Control Statements
Control Structure
Control structure actually controls the flow of execution of a program. Following are the
several control structure supported by javascript.
if … else
switch case
do while loop
while loop
for loop
If … else
The if statement is the fundamental control statement that allows JavaScript to make
decisions and execute statements conditionally.
Syntax
if (expression){
Statement(s) to be executed if expression is true
}
Example
<script type="text/javascript">
<!--
var age = 20;
if( age > 18 ){
document.write("<b>Qualifies for driving</b>");
}
//-->
</script>
Switch case
The basic syntax of the switch statement is to give an expression to evaluate and several
different statements to execute based on the value of the expression. The interpreter checks
each case against the value of the expression until a match is found. If nothing matches, a
default condition will be used.
Syntax
switch (expression) {
case condition 1: statement(s)
break;
case condition 2: statement(s)
break;
...
case condition n: statement(s)
break;
default: statement(s)
}
Example
<script type="text/javascript">
<!--
var grade='A';
document.write("Entering switch block<br/>");
switch (grade) {
case 'A': document.write("Good job<br/>");
break;
case 'B': document.write("Pretty good<br/>");
break;
case 'C': document.write("Passed<br/>");
break;
case 'D': document.write("Not so good<br/>");
break;
case 'F': document.write("Failed<br/>");
break;
default: document.write("Unknown grade<br/>")
}
document.write("Exiting switch block");
//-->
</script>
Do while Loop
The do...while loop is similar to the while loop except that the condition check happens at the
end of the loop. This means that the loop will always be executed at least once, even if the
condition is false.
Syntax
do{
Statement(s) to be executed;
} while (expression);
Example
<script type="text/javascript">
<!--
var count = 0;
document.write("Starting Loop" + "<br/>");
do{
document.write("Current Count : " + count + "<br/>");
count++;
}while (count < 0);
document.write("Loop stopped!");
//-->
</script>
This will produce following result −
Starting Loop
Current Count : 0
Loop stopped!
While Loop
The purpose of a while loop is to execute a statement or code block repeatedly as long as
expression is true. Once expression becomes false, the loop will be exited.
Syntax
while (expression){
Statement(s) to be executed if expression is true
}
Example
<script type="text/javascript">
<!--
var count = 0;
document.write("Starting Loop" + "<br/>");
while (count < 10){
document.write("Current Count : " + count + "<br/>");
count++;
}
document.write("Loop stopped!");
//-->
</script>
This will produce following result −
Starting Loop
Current Count : 0
Current Count : 1
Current Count : 2
Current Count : 3
Current Count : 4
Current Count : 5
Current Count : 6
Current Count : 7
Current Count : 8
Current Count : 9
Loop stopped!
For Loop
The for loop is the most compact form of looping and includes the following three important
parts −
The loop initialization where we initialize our counter to a starting value. The
initialization statement is executed before the loop begins.
The test statement which will test if the given condition is true or not. If condition is
true then code given inside the loop will be executed otherwise loop will come out.
The iteration statement where you can increase or decrease your counter.
Syntax
for (initialization; test condition; iteration statement){
Statement(s) to be executed if test condition is true
}
Example
<script type="text/javascript">
<!--
var count;
document.write("Starting Loop" + "<br/>");
for(count = 0; count < 10; count++){
document.write("Current Count : " + count );
document.write("<br/>");
}
document.write("Loop stopped!");
//-->
</script>
This will produce following result which is similar to while loop −
Starting Loop
Current Count : 0
Current Count : 1
Current Count : 2
Current Count : 3
Current Count : 4
Current Count : 5
Current Count : 6
Current Count : 7
Current Count : 8
Current Count : 9
Loop stopped!
<p id="demo"></p>
</script>
</body>
</html>
Output
Pattern Matching using Regular Expression:
^ Matches the position at the beginning of the searched string. For example
^CF matches any string starting 'CF'.
$ Matches the position at the end of the searched string. For example EZ$
matches any string ending 'EZ'.
uses of '?'.
{n,m} Matches at least n times and at most m times, where n and m are
nonnegative integers ( n <= m). For example, 'o{2,4}' matches the first
four o's in "zooooom", but not the o in "zero".
? When '?' immediately follows any of the qualifiers (*, +, ?, {n}, {n,},
{n,m}), the matching pattern is non-greedy. While the default pattern
matching is to match as much of the searched string as possible, a non-
greedy pattern matches as little of the searched string as possible. For
example, 'o+?' matches a single o in "zooom", while 'o+' matches all the
o's.
[charlist] Matches any single character in charlist. For example, '[aeiou]' matches
the e in "Relativity".
Character(s) Matches in searched string
[^charlist] Matches any single character not in charlist. For example, '[^aeiou]'
matches the R in "Relativity".
[a-z] Matches any single character in the specified character range. For
example, '[a-z]' matches any lowercase alphabetic character in the range
"a" through "z", inclusive.
[^m-z] Matches any single character not in the specified character range. For
example, '[^m-z]' matches any character except those in the range "m"
through "z", inclusive.
\b Matches a word boundary (the position between a word and a space). For
example, "le\b" matches the "le" of "file" in the searched string "lengthy
file name", not the "le" in "lengthy".
// input string
let str = "Visit geeksforGeeks!";
console.log(n);
console.log(n);
}
myFunction();
Output:
6
-1
Primitive Operations & Expression in javascript:
At a high level, an expression is a valid unit of code that resolves to a value. There are two
types of expressions: those that have side effects (such as assigning values) and those that
purely evaluate.
The expression x = 7 is an example of the first type. This expression uses the = operator to
assign the value seven to the variable x. The expression itself evaluates to 7.
The expression 3 + 4 is an example of the second type. This expression uses the + operator to
add 3 and 4 together and produces a value, 7. However, if it's not eventually part of a bigger
construct (for example, a variable declaration like const z = 3 + 4), its result will be
immediately discarded — this is usually a programmer mistake because the evaluation
doesn't produce any effects.
As the examples above also illustrate, all complex expressions are joined by operators, such
as = and +. In this section, we will introduce the following operators:
Assignment operators
Comparison operators
Arithmetic operators
Bitwise operators
Logical operators
BigInt operators
String operators
Conditional (ternary) operator
Comma operator
Unary operators
Relational operators
The precedence of operators determines the order they are applied when evaluating an
expression. For example:
const x = 1 + 2 * 3;
const y = 2 * 3 + 1;
Copy to Clipboard
Despite * and + coming in different orders, both expressions would result in 7 because * has
precedence over +, so the *-joined expression will always be evaluated first. You can
override operator precedence by using parentheses (which creates a grouped expression —
the basic expression). To see a complete table of operator precedence as well as various
caveats, see the Operator Precedence Reference page.
JavaScript has both binary and unary operators, and one special ternary operator, the
conditional operator. A binary operator requires two operands, one before the operator and
one after the operator:
operand1 operator operand2
Copy to Clipboard
For example, 3 + 4 or x * y. This form is called an infix binary operator, because the operator
is placed between two operands. All binary operators in JavaScript are infix.
A unary operator requires a single operand, either before or after the operator:
operator operand
operand operator
Copy to Clipboard
For example, x++ or ++x. The operator operand form is called a prefix unary operator, and
the operand operator form is called a postfix unary operator. ++ and -- are the only postfix
operators in JavaScript — all other operators, like !, typeof, etc. are prefix.
Assignment operators
An assignment operator assigns a value to its left operand based on the value of its right
operand. The simple assignment operator is equal (=), which assigns the value of its right
operand to its left operand. That is, x = f() is an assignment expression that assigns the value
of f() to x.
There are also compound assignment operators that are shorthand for the operations listed in
the following table:
Name Shorthand operator Meaning
Assignment x = f() x = f()
Addition assignment x += f() x = x + f()
Name Shorthand operator Meaning
Subtraction assignment x -= f() x = x - f()
Multiplication assignment x *= f() x = x * f()
Division assignment x /= f() x = x / f()
Remainder assignment x %= f() x = x % f()
Exponentiation assignment x **= f() x = x ** f()
Left shift assignment x <<= f() x = x << f()
Right shift assignment x >>= f() x = x >> f()
Unsigned right shift assignment x >>>= f() x = x >>> f()
Bitwise AND assignment x &= f() x = x & f()
Bitwise XOR assignment x ^= f() x = x ^ f()
Bitwise OR assignment x |= f() x = x | f()
Logical AND assignment x &&= f() x && (x = f())
Logical OR assignment x ||= f() x || (x = f())
Nullish coalescing assignment x ??= f() x ?? (x = f())
Assigning to properties
obj.x = 3;
console.log(obj.x); // Prints 3.
console.log(obj); // Prints { x: 3 }.
In strict mode, the code above throws, because one cannot assign properties to primitives.
It is an error to assign values to unmodifiable properties or to properties of an expression
without properties (null or undefined).
Destructuring
// without destructuring
const one = foo[0];
const two = foo[1];
const three = foo[2];
// with destructuring
const [one, two, three] = foo;
Copy to Clipboard
In general, assignments are used within a variable declaration (i.e., with const, let, or var) or
as standalone statements).
// Declares a variable x and initializes it to the result of f().
// The result of the x = f() assignment expression is discarded.
let x = f();
However, like other expressions, assignment expressions like x = f() evaluate into a result
value. Although this result value is usually not used, it can then be used by another
expression.
By chaining or nesting an assignment expression, its result can itself be assigned to another
variable. It can be logged, it can be put inside an array literal or function call, and so on.
let x;
const y = (x = f()); // Or equivalently: const y = x = f();
console.log(y); // Logs the return value of the assignment x = f().
The evaluation result matches the expression to the right of the = sign in the "Meaning"
column of the table above. That means that x = f() evaluates into whatever f()'s result is, x +=
f() evaluates into the resulting sum x + f(), x **= f() evaluates into the resulting power x ** y,
and so on.
In the case of logical assignments, x &&= f(), x ||= f(), and x ??= f(), the return value is that
of the logical operation without the assignment, so x && f(), x || f(), and x ?? f(), respectively.
When chaining these expressions without parentheses or other grouping operators like array
literals, the assignment expressions are grouped right to left (they are right-associative), but
they are evaluated left to right.
Note that, for all assignment operators other than = itself, the resulting values are always
based on the operands' values before the operation.
For example, assume that the following functions f and g and the variables x and y have been
declared:
function f() {
console.log("F!");
return 2;
}
function g() {
console.log("G!");
return 3;
}
let x, y;
Copy to Clipboard
Evaluation example 1
x[f()] = g() also evaluates from left to right. (This example assumes that x is already assigned
to some object. For more information about objects, read Working with Objects.)
In particular, putting a variable chain in a const, let, or var statement often does not work.
Only the outermost/leftmost variable would get declared; other variables within the
assignment chain are not declared by the const/let/var statement. For example:
const z = y = x = f();
Copy to Clipboard
This statement seemingly declares the variables x, y, and z. However, it only actually
declares the variable z. y and x are either invalid references to nonexistent variables (in strict
mode) or, worse, would implicitly create global variables for x and y in sloppy mode.
Comparison operators
A comparison operator compares its operands and returns a logical value based on whether
the comparison is true. The operands can be numerical, string, logical, or object values.
Strings are compared based on standard lexicographical ordering, using Unicode values. In
most cases, if the two operands are not of the same type, JavaScript attempts to convert them
to an appropriate type for the comparison. This behavior generally results in comparing the
operands numerically. The sole exceptions to type conversion within comparisons involve
the === and !== operators, which perform strict equality and inequality comparisons. These
operators do not attempt to convert the operands to compatible types before checking
equality. The following table describes the comparison operators in terms of this sample
code:
const var1 = 3;
const var2 = 4;
Copy to Clipboard
Comparison operators
Examples
Operator Description returning
true
3 == var1
Equal (==) Returns true if the operands are equal.
"3" == var1
3 == '3'
var1 != 4
Not equal (!=) Returns true if the operands are not equal.
var2 != "3"
Returns true if the operands are equal and of
Strict
the same type. See 3 === var1
equal (===)
also Object.is and sameness in JS.
Comparison operators
Examples
Operator Description returning
true
Strict not Returns true if the operands are of the same var1 !== "3"
equal (!==) type but not equal, or are of different type. 3 !== '3'
Greater Returns true if the left operand is greater than var2 > var1
than (>) the right operand. "12" > 2
Greater than or Returns true if the left operand is greater than var2 >= var1
equal (>=) or equal to the right operand. var1 >= 3
Returns true if the left operand is less than var1 < var2
Less than (<)
the right operand. "2" < 12
Less than or Returns true if the left operand is less than or var1 <= var2
equal (<=) equal to the right operand. var2 <= 5
Note: => is not a comparison operator but rather is the notation for Arrow functions.
Arithmetic operators
An arithmetic operator takes numerical values (either literals or variables) as their operands
and returns a single numerical value. The standard arithmetic operators are addition (+),
subtraction (-), multiplication (*), and division (/). These operators work as they do in most
other programming languages when used with floating point numbers (in particular, note that
division by zero produces Infinity). For example:
1 / 2; // 0.5
1 / 2 === 1.0 / 2.0; // this is true
Copy to Clipboard
In addition to the standard arithmetic operations (+, -, *, /), JavaScript provides the arithmetic
operators listed in the following table:
Arithmetic operators
Operator Description Example
Binary operator. Returns the
Remainder (%) integer remainder of dividing the 12 % 5 returns 2.
two operands.
Unary operator. Adds one to its
operand. If used as a prefix If x is 3, then +
operator (++x), returns the value +x sets x to 4 and returns
Increment (++) of its operand after adding one; if 4, whereas x++ returns 3
used as a postfix operator (x++), and, only then, sets x to
returns the value of its operand 4.
before adding one.
Decrement (--) Unary operator. Subtracts one If x is 3, then --
from its operand. The return x sets x to 2 and returns
value is analogous to that for the 2, whereas x-- returns 3
Arithmetic operators
Operator Description Example
and, only then, sets x to
increment operator.
2.
Unary Unary operator. Returns the If x is 3, then -x returns -
negation (-) negation of its operand. 3.
Unary operator. Attempts +"3" returns 3.
Unary plus (+) to convert the operand to a
number, if it is not already. +true returns 1.
Calculates the base to
Exponentiation 2 ** 3 returns 8.
the exponent power, that
operator (**) 10 ** -1 returns 0.1.
is, base^exponent
Bitwise operators
A bitwise operator treats their operands as a set of 32 bits (zeros and ones), rather than as
decimal, hexadecimal, or octal numbers. For example, the decimal number nine has a binary
representation of 1001. Bitwise operators perform their operations on such binary
representations, but they return standard JavaScript numerical values.
Copy to Clipboard
Each bit in the first operand is paired with the corresponding bit in the second
operand: first bit to first bit, second bit to second bit, and so on.
The operator is applied to each pair of bits, and the result is constructed bitwise.
For example, the binary representation of nine is 1001, and the binary representation of
fifteen is 1111. So, when the bitwise operators are applied to these values, the results are as
follows:
Expression Result Binary Description
15 & 9 9 1111 & 1001 = 1001
15 | 9 15 1111 | 1001 = 1111
15 ^ 9 6 1111 ^ 1001 = 0110
~15 -16 ~ 0000 0000 … 0000 1111 = 1111 1111 … 1111 0000
~9 -10 ~ 0000 0000 … 0000 1001 = 1111 1111 … 1111 0110
Note that all 32 bits are inverted using the Bitwise NOT operator, and that values with the
most significant (left-most) bit set to 1 represent negative numbers (two's-complement
representation). ~x evaluates to the same value that -x - 1 evaluates to.
The bitwise shift operators take two operands: the first is a quantity to be shifted, and the
second specifies the number of bit positions by which the first operand is to be shifted. The
direction of the shift operation is controlled by the operator used.
Shift operators convert their operands to thirty-two-bit integers and return a result of either
type Number or BigInt: specifically, if the type of the left operand is BigInt, they
return BigInt; otherwise, they return Number.
Logical operators
Logical operators are typically used with Boolean (logical) values; when they are, they return
a Boolean value. However, the && and || operators actually return the value of one of the
specified operands, so if these operators are used with non-Boolean values, they may return a
non-Boolean value. The logical operators are described in the following table.
Logical operators
Operator Usage Description
Returns expr1 if it can be converted to false;
expr1
Logical otherwise, returns expr2. Thus, when used with
&&
AND (&&) Boolean values, && returns true if both operands are
expr2
true; otherwise, returns false.
Returns expr1 if it can be converted to true;
Logical expr1 || otherwise, returns expr2. Thus, when used with
OR (||) expr2 Boolean values, || returns true if either operand is
true; if both are false, returns false.
Logical Returns false if its single operand that can be
!expr
NOT (!) converted to true; otherwise, returns true.
Examples of expressions that can be converted to false are those that evaluate to null, 0, NaN,
the empty string (""), or undefined.
The following code shows examples of the && (logical AND) operator.
const a1 = true && true; // t && t returns true
const a2 = true && false; // t && f returns false
const a3 = false && true; // f && t returns false
const a4 = false && 3 === 4; // f && f returns false
const a5 = "Cat" && "Dog"; // t && t returns Dog
const a6 = false && "Cat"; // f && t returns false
const a7 = "Cat" && false; // t && f returns false
Copy to Clipboard
Short-circuit evaluation
As logical expressions are evaluated left to right, they are tested for possible "short-circuit"
evaluation using the following rules:
The rules of logic guarantee that these evaluations are always correct. Note that
the anything part of the above expressions is not evaluated, so any side effects of doing so do
not take effect.
Note that for the second case, in modern code you can use the Nullish coalescing
operator (??) that works like ||, but it only returns the second expression, when the first one is
"nullish", i.e. null or undefined. It is thus the better alternative to provide defaults, when
values like '' or 0 are valid values for the first expression, too.
BigInt operators
Most operators that can be used between numbers can be used between BigInt values as well.
// BigInt addition
const a = 1n + 2n; // 3n
// Division with BigInts round towards zero
const b = 1n / 2n; // 0n
// Bitwise operations with BigInts do not truncate either side
const c = 40000000000000000n >> 2n; // 10000000000000000n
Copy to Clipboard
One exception is unsigned right shift (>>>), which is not defined for BigInt values. This is
because a BigInt does not have a fixed width, so technically it does not have a "highest bit".
const d = 8n >>> 2n; // TypeError: BigInts have no unsigned right shift, use >> instead
Copy to Clipboard
BigInts and numbers are not mutually replaceable — you cannot mix them in calculations.
const a = 1n + 2; // TypeError: Cannot mix BigInt and other types
This is because BigInt is neither a subset nor a superset of numbers. BigInts have higher
precision than numbers when representing large integers, but cannot represent decimals, so
implicit conversion on either side might lose precision. Use explicit conversion to signal
whether you wish the operation to be a number operation or a BigInt one.
const a = Number(1n) + 2; // 3
const b = 1n + BigInt(2); // 3n
String operators
In addition to the comparison operators, which can be used on string values, the
concatenation operator (+) concatenates two string values together, returning another string
that is the union of the two operand strings.
For example,
console.log("my " + "string"); // console logs the string "my string".
Copy to Clipboard
For example,
let mystring = "alpha";
mystring += "bet"; // evaluates to "alphabet" and assigns this value to mystring.
Copy to Clipboard
The conditional operator is the only JavaScript operator that takes three operands. The
operator can have one of two values based on a condition. The syntax is:
condition ? val1 : val2
Copy to Clipboard
If condition is true, the operator has the value of val1. Otherwise it has the value of val2. You
can use the conditional operator anywhere you would use a standard operator.
For example,
const status = age >= 18 ? "adult" : "minor";
Copy to Clipboard
This statement assigns the value "adult" to the variable status if age is eighteen or more.
Otherwise, it assigns the value "minor" to status.
Comma operator
The comma operator (,) evaluates both of its operands and returns the value of the last
operand. This operator is primarily used inside a for loop, to allow multiple variables to be
updated each time through the loop. It is regarded bad style to use it elsewhere, when it is not
necessary. Often two separate statements can and should be used instead.
For example, if a is a 2-dimensional array with 10 elements on a side, the following code uses
the comma operator to update two variables at once. The code prints the values of the
diagonal elements in the array:
const x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const a = [x, x, x, x, x];
Unary operators
delete
where object is the name of an object, property is an existing property, and propertyKey is a
string or symbol referring to an existing property.
If the delete operator succeeds, it removes the property from the object. Trying to access it
afterwards will yield undefined. The delete operator returns true if the operation is possible; it
returns false if the operation is not possible.
delete Math.PI; // returns false (cannot delete non-configurable properties)
const myObj = { h: 4 };
delete myObj.h; // returns true (can delete user-defined properties)
Copy to Clipboard
Since arrays are just objects, it's technically possible to delete elements from them. This is
however regarded as a bad practice, try to avoid it. When you delete an array property, the
array length is not affected and other elements are not re-indexed. To achieve that behavior, it
is much better to just overwrite the element with the value undefined. To actually manipulate
the array, use the various array methods such as splice.
typeof
The typeof operator returns a string indicating the type of the unevaluated
operand. operand is the string, variable, keyword, or object for which the type is to be
returned. The parentheses are optional.
The typeof operator returns the following results for these variables:
typeof myFun; // returns "function"
typeof shape; // returns "string"
typeof size; // returns "number"
typeof foo; // returns "object"
typeof today; // returns "object"
typeof doesntExist; // returns "undefined"
Copy to Clipboard
For the keywords true and null, the typeof operator returns the following results:
typeof true; // returns "boolean"
typeof null; // returns "object"
Copy to Clipboard
For a number or string, the typeof operator returns the following results:
typeof 62; // returns "number"
typeof "Hello world"; // returns "string"
Copy to Clipboard
For property values, the typeof operator returns the type of value the property contains:
typeof document.lastModified; // returns "string"
typeof window.length; // returns "number"
typeof Math.LN2; // returns "number"
Copy to Clipboard
For methods and functions, the typeof operator returns results as follows:
typeof blur; // returns "function"
typeof eval; // returns "function"
typeof parseInt; // returns "function"
typeof shape.split; // returns "function"
Copy to Clipboard
For predefined objects, the typeof operator returns results as follows:
typeof Date; // returns "function"
typeof Function; // returns "function"
typeof Math; // returns "object"
typeof Option; // returns "function"
typeof String; // returns "function"
Copy to Clipboard
void
Relational operators
A relational operator compares its operands and returns a Boolean value based on whether the
comparison is true.
in
The in operator returns true if the specified property is in the specified object. The syntax is:
propNameOrNumber in objectName
Copy to Clipboard
// built-in objects
"PI" in Math; // returns true
const myString = new String("coral");
"length" in myString; // returns true
// Custom objects
const mycar = { make: "Honda", model: "Accord", year: 1998 };
"make" in mycar; // returns true
"model" in mycar; // returns true
Copy to Clipboard
instanceof
The instanceof operator returns true if the specified object is of the specified object type. The
syntax is:
objectName instanceof objectType
Copy to Clipboard
where objectName is the name of the object to compare to objectType, and objectType is an
object type, such as Date or Array.
Use instanceof when you need to confirm the type of an object at runtime. For example, when
catching exceptions, you can branch to different exception-handling code depending on the
type of exception thrown.
For example, the following code uses instanceof to determine whether theDay is
a Date object. Because theDay is a Date object, the statements in the if statement execute.
const theDay = new Date(1995, 12, 17);
if (theDay instanceof Date) {
// statements to execute
}
Copy to Clipboard
Basic expressions
All operators eventually operate on one or more basic expressions. These basic expressions
include identifiers and literals, but there are a few other kinds as well. They are briefly
introduced below, and their semantics are described in detail in their respective reference
sections.
this
Use the this keyword to refer to the current object. In general, this refers to the calling object
in a method. Use this either with the dot or the bracket notation:
this["propertyName"];
this.propertyName;
Copy to Clipboard
Suppose a function called validate validates an object's value property, given the object and
the high and low values:
function validate(obj, lowval, hival) {
if (obj.value < lowval || obj.value > hival) {
console.log("Invalid Value!");
}
}
Copy to Clipboard
You could call validate in each form element's onChange event handler, using this to pass it
to the form element, as in the following example:
<p>Enter a number between 18 and 99:</p>
<input type="text" name="age" size="3" onChange="validate(this, 18, 99);" />
Copy to Clipboard
Grouping operator
The grouping operator ( ) controls the precedence of evaluation in expressions. For example,
you can override multiplication and division first, then addition and subtraction to evaluate
addition first.
const a = 1;
const b = 2;
const c = 3;
// default precedence
a + b * c // 7
// evaluated by default like this
a + (b * c) // 7
// which is equivalent to
a * c + b * c // 9
Explanation
Model: Model represents the structure of data, the format and the constraints with which it
is stored. It maintains the data of the application. Essentially, it is the database part of the
application. View: View is what is presented to the user. Views utilize the Model and
present data in a form in which the user wants. A user can also be allowed to make changes
to the data presented to the user. They consist of static and dynamic pages which are
rendered or sent to the user when the user requests
them. Controller:Controller controls the requests of the user and then generates
appropriate response which is fed to the viewer. Typically, the user interacts with the View,
which in turn generates the appropriate request, this request will be handled by a controller.
The controller renders the appropriate view with the model data as a response. So, to sum it
up:
Model is data part.
View is User Interface part.
Controller is request-response handler.
MVC architecture
Now, lets get started with the application. npm init is used here to generate
a package.json and app.js file.
npm-init
As the name suggests, there are three folders, called models, views, controllers which will
help in the mvc architecture implementation. npm is used to install the basic npm packages
to get started.
npm-package-install-snip
mvc-project-structure snip
. It tells the app that use the variable routes if ‘/’ is requested. Then it looks for the routes
variable. It finds it in the app.js file here:
Routes requires
. Now it looks in the gfgIndex.js file in the routes folder of our node app to look for the
code to execute when the ‘/’ route is hit. It finds the following code.
This code basically says that render the index.hanblebars if the user is logged in. To
check if the user is logged in, it runs the function ensureAuthenticated. This function
basically says that if the user is logged in, render the index.handlebars file else redirect
the user to the /users/login route.
GfgUsersjs login route snip
This code tells the app to render the index.handlebars file when the GET ‘/’ is called. So,
now it goes to the views folder and look for the index.handlebars and renders it to the
user. This is how the views-controller part of the architecture works in the app. I believe
the above program flow is clear to the reader.
Lets navigate to http://localhost:3000/users/register. So, the app breaks the route into
two pieces:/users and /register and asks itself something like “Oh okay! The users wants
to see /users route and then /register . The app looks for the ‘/users’ in its app.js file and
finds it here.
. Then it looks for the ‘users’ variable to use when /users path is hit which can be found
in the app.js file:
Routes requires
. So, it goes to the gfgUsers.js file in the routes folder and looks for the route /register.
Note that the /users/register finds itself in gfgUsers.js file as /register. It asks the
browser to render ‘register.handlebars’ file. This is the view-controller arch.
implementation going on. Second Part of Registration Now, lets register a new user.
Register a new user snap.
image:https://media.geeksforgeeks.org/wp-content/uploads/register-a-new-user-snap.png
After clicking on submit, the data is taken, POSTed to the ‘/register’ route for
processing. This controller validates the incoming data for errors, then creates a new
variable called newUser with the User modelled with all the data and the calls save() on
it to actually save the data to the user.
After the user is created, the ‘/register’ controller asks the browser to redirect the user
to ‘/login’ page. This is the model-view-controller architecture implementation.
In this section, we will learn about the Node.js process model and understand why we
should use Node.js.
In the traditional web server model, each request is handled by a dedicated thread from the
thread pool. If no thread is available in the thread pool at any point of time then the request
waits till the next available thread. Dedicated thread executes a particular request and does
not return to thread pool until it completes the execution and returns a response.
Node.js processes user requests differently when compared to a traditional web server
model. Node.js runs in a single process and the application code runs in a single thread and
thereby needs less resources than other platforms. All the user requests to your web
application will be handled by a single thread and all the I/O work or long running job is
performed asynchronously for a particular request. So, this single thread doesn't have to
wait for the request to complete and is free to handle the next request. When asynchronous
I/O work completes then it processes the request further and sends the response.
An event loop is constantly watching for the events to be raised for an asynchronous job
and executing callback function when the job completes. Internally, Node.js uses libev for
the event loop which in turn uses internal C++ thread pool to provide asynchronous I/O.
The following figure illustrates asynchronous web server model using Node.js.
Node.js process model increases the performance and scalability with a few caveats.
Node.js is not fit for an application which performs CPU-intensive operations like image
processing or other heavy computation work because it takes time to process a request and
thereby blocks the single thread.