Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
4K views

JavaScript Course v2.2

The document provides an overview of JavaScript including its history, syntax, data types, operators, functions and more. It covers features introduced in ES5 through ES11 and describes concepts like variables, scope, objects, functions and iterators.

Uploaded by

dnziyad
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4K views

JavaScript Course v2.2

The document provides an overview of JavaScript including its history, syntax, data types, operators, functions and more. It covers features introduced in ES5 through ES11 and describes concepts like variables, scope, objects, functions and iterators.

Uploaded by

dnziyad
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 280

BASICS INFORMATION BEFORE YOU START 1

JAVASCRIPT 2
EXTERNAL JAVASCRIPT ADVANTAGES 2
JAVASCRIPT AND ECMA SCRIPT RELATION 2
NAMESPACING IN JAVASCRIPT 2
JAVASCRIPT VERSIONS 3
ECMASCRIPT 2009 (ES5) 5
ECMASCRIPT 2015 (ES6) 7
ECMASCRIPT 2016 (ES7) 8
ECMASCRIPT 2017 (ES8) 9
ECMASCRIPT 2018 (ES9) 10
ECMASCRIPT 2019 (ES10) 11
ECMASCRIPT 2020 (ES11) 12
OPTIONAL CHAINING OPERATOR → ES11 12
NULLISH COALESCING OPERATOR → ES11 12
JAVASCRIPT SYNTAX 14
JAVASCRIPT VALUES 14
JAVASCRIPT STATEMENTS 14
JAVASCRIPT EXPRESSIONS 14
JAVASCRIPT IDENTIFIERS 14
JAVASCRIPT IS CASE SENSITIVE 14
JAVASCRIPT AND CAMEL CASE 15
JAVASCRIPT CHARACTER SET 15
JAVASCRIPT COMMENTS 15
JAVASCRIPT GLOBAL 16
JAVASCRIPT GLOBAL PROPERTIES 16
JAVASCRIPT GLOBAL FUNCTIONS 16
FUNCTIONS OR METHODS? 17
ENCODEURI & ENCODEURICOMPONENT 17
UNIFORM RESOURCE IDENTIFIER (URI) 18
JAVASCRIPT SCOPE 19
1. LOCAL JAVASCRIPT VARIABLES 19
2. GLOBAL JAVASCRIPT VARIABLES 19
3. BLOCK SCOPE 19
JAVASCRIPT VARIABLES 20
AUTOMATICALLY GLOBAL 20
STRICT MODE → ES5 20
GLOBAL VARIABLES IN HTML 20
THE LIFETIME OF JAVASCRIPT VARIABLES 20
DECLARING (CREATING) VARIABLES 21
1. JAVASCRIPT VAR 21
2. JAVASCRIPT LET → ES6 21
3. JAVASCRIPT CONST → ES6 23
JAVASCRIPT HOISTING 26
JAVASCRIPT DECLARATIONS ARE HOISTED 26
JAVASCRIPT INITIALIZATIONS ARE NOT HOISTED 26
NOTE - TO AVOID HOISTING, YOU CAN RUN JAVASCRIPT IN STRICT MODE BY USING “USE STRICT ” ON
TOP OF THE CODE. 26
DECLARE YOUR VARIABLES AT THE TOP ! 26
ARITHMETIC OPERATORS 27
OPERATOR PRECEDENCE 27
EXPONENTIATION OPERATOR → ES7 30
DATA TYPES 31
1. PRIMITIVE DATA TYPE (IMMUTABLE) 31
2. COMPLEX DATA TYPE 31
OBJECT TYPES 31
JAVASCRIPT A (LOOSELY) DYNAMICALLY TYPED LANGUAGE 31
PASSED BY VALUE & PASSED BY REFERENCE. 31
NOTE: 32
STRINGS 33
ESCAPE CHARACTER 33
BREAKING LONG CODE LINES 33
STRINGS CAN BE OBJECTS 34
TEMPLATE LITERALS → ES6 34
STRING METHODS AND PROPERTIES 35
FINDING A STRING IN A STRING 35
- ALL METHODS ABOVE, ARE CASE SENSITIVE. 36
SEARCHING FOR A STRING IN A STRING 36
SEARCH VS INDEXOF ? 36
EXTRACTING STRING PARTS 36
REPLACING STRING CONTENT 37
CONVERTING TO UPPER AND LOWER CASE 38
THE CONCAT(VALUETOADDBTW, TXTTOCONCAT …) METHOD 38
THE TRIM() METHOD → ES5 38
EXTRACTING STRING CHARACTERS 38
REPEATING A STRING → ES6 39
CONVERTING A STRING TO AN ARRAY 39
COMPLETE 40
NUMBERS 41
JAVASCRIPT NUMBERS ARE ALWAYS 64-BIT FLOATING POINT 41
PRECISION 41
NUMERIC STRINGS 41
NAN - NOT A NUMBER 42
INFINITY 42
HEXADECIMAL 42
NUMBERS CAN BE OBJECTS 42
NUMBER METHODS 43
THE TOEXPONENTIAL() METHOD 43
THE TOFIXED() METHOD 43
THE TOPRECISION() METHOD 43
THE VALUEOF() METHOD 44
CONVERTING VARIABLES TO NUMBERS 44
NUMBER SAFETY CHECKING METHODS → ES6 45
NUMBER PROPERTIES 45
NEW NUMBER PROPERTIES → ES6 46
NUMBER TYPE CHECKING METHODS → ES6 46

2
BIGINT - ARBITRARY PRECISION INTEGERS → ES10 47
COMPLETE NUMBER REFERENCE. 47
BOOLEANS 48
THE BOOLEAN() FUNCTION 48
BOOLEANS CAN BE OBJECTS 48
IMPLICIT TYPE COERCION IN JAVASCRIPT. 49
STRING COERCION 49
BOOLEAN COERCION 49
EQUALITY COERCION 49
SYMBOL → ES6 50
CREATE A SYMBOL 50
SHARED SYMBOLS IN THE GLOBAL SYMBOL REGISTRY 50
“HIDDEN” PROPERTIES 50
SYMBOLS IN A LITERAL 51
SYMBOLS ARE SKIPPED BY FOR…IN 51
FINDING SYMBOL PROPERTIES ON OBJECTS 51
DISPLAY SYMBOL 51
SYMBOL DESCRIPTION → ES10 51
SYMBOL REFERENCE 52
FUNCTIONS 53
JAVASCRIPT FUNCTION SYNTAX 53
FUNCTION PARAMETERS & ARGUMENTS 54
CONVERTING ARGUMENTS TO AN ARRAY 55
DEFAULT, REST AND SPREAD PARAMETERS → ES6 55
JAVASCRIPT FUNCTION INVOCATION “CALL” 56
SELF-INVOKING FUNCTIONS 57
FUNCTIONS CAN BE USED AS VALUES OR AS EXPRESSION 57
FUNCTIONS ARE OBJECTS 57
ARROW FUNCTIONS → ES6 57
FUNCTION RETURN 58
FUNCTION CALL 58
JAVASCRIPT FUNCTION APPLY 59
JAVASCRIPT FUNCTION BIND → ES5 60
THE DIFFERENCE BETWEEN CALL(), APPLY() AND BIND() 61
JAVASCRIPT CLOSURES 61
NEW FUNCTION.TOSTRING() → ES10 62
CURRYING IN JAVASCRIPT 62
VOID OPERATOR 64
SYNTAX 64
DESCRIPTION 64
ITERATORS → ES6 65
ITERABLES 65
ITERATORS 65
ITERATORS THAT ARE ITERABLE 66
GENERATORS → ES6 68
GENERATOR FUNCTIONS 68
FUNCTION* F(…) OR FUNCTION *F(…)? 69
GENERATOR COMPOSITION 69
“YIELD” IS A TWO-WAY STREET 70
YIELD BINDS LOOSELY 70

3
USING GENERATORS FOR ITERABLES 71
USES OF GENERATORS 71
ADVANTAGES OF GENERATORS 73
DISADVANTAGES OF GENERATORS 73
OBJECTS 75
OBJECT (CREATE) DEFINITION 75
JAVASCRIPT OBJECTS ARE MUTABLE 76
OBJECT PROPERTIES 76
ENHANCED OBJECT LITERALS → ES6 78
DESTRUCTURING OBJECT → ES6 79
OBJECT METHODS 80
THE THIS KEYWORD 80
THE IN OPERATOR 80
OBJECTS ARE PASSED BY REFERENCE 81
DISPLAY OBJECTS 82
OBJECT AND INTERNAL METHODS 83
OBJECT CONSTRUCTORS 85
THE THIS KEYWORD 85
ADDING A PROPERTY TO A CONSTRUCTOR 85
OBJECT PROTOTYPES 86
PROTOTYPE-BASED PROGRAMMING 86
THREE DIFFERENT KINDS OF PROTOTYPAL OBJECT-ORIENTED. 87
OBJECT METHODS 90
ES5 OBJECT METHODS 90
ES6 OBJECT METHODS 91
ES8 OBJECT METHODS 92
REST/SPREAD OPERATOR FOR OBJECTS → ES9 93
OBJECT.FROMENTRIES(ITERABLE) 93
THIS KEYWORD 94
STANDARDIZED GLOBALTHIS OBJECT → ES10 96
ARRAYS 97
CREATING AN ARRAY 97
ACCESS THE ELEMENTS OF AN ARRAY 97
CHANGING AN ARRAY ELEMENT 97
ACCESS THE FULL ARRAY 97
ARRAYS ARE OBJECTS 97
ARRAY ELEMENTS CAN BE OBJECTS 98
ARRAY PROPERTIES 98
ACCESSING THE LAST ARRAY ELEMENT 98
DESTRUCTRING ARRAY → ES6 98
REST/SPREAD OPERATOR FOR ARRAYS → ES6 98
ASSOCIATIVE ARRAYS 99
THE DIFFERENCE BETWEEN ARRAYS AND OBJECTS IN JAVASCRIPT 99
HOW TO RECOGNIZE AN ARRAY 99
DECLARES A THREE DIMENSIONAL ARRAY 100
ARRAY METHODS 101
CONVERTING ARRAYS TO STRINGS 101
AUTOMATIC TOSTRING() 101
POPPING AND PUSHING 101

4
SHIFTING ELEMENTS 101
UNSHIFTING ELEMENTS 101
DELETING ELEMENTS (DON’T USE IT) 102
SPLICING AN ARRAY 102
MERGING (CONCATENATING) ARRAYS 102
SLICING AN ARRAY 103
REVERSING AN ARRAY 103
SORTING AN ARRAY 103
NUMERIC SORT 104
THE COMPARE FUNCTION 104
SORTING AN ARRAY IN RANDOM ORDER 104
FIND THE HIGHEST (OR LOWEST) ARRAY VALUE 104
HOME BUILT METHODS FOR MIN AND MAX 105
SORTING OBJECT ARRAYS 105
ARRAY ITERATION METHODS 107
ARRAYVAR.FOREACH() → ES5 107
ARRAYVAR.MAP() →ES5 107
ARRAYVAR.FILTER() → ES5 107
ARRAYVAR.REDUCE() & ARRAYVAR.REDUCERIGHT() → ES5 108
ARRAYVAR.EVERY() → ES5 108
ARRAYVAR.SOME() → ES5 108
ARRAYVAR.INDEXOF() → ES5 109
ARRAYVAR.LASTINDEXOF() → ES5 109
ARRAYVAR.ENTRIES () → ES6 109
ARRAYVAR.FIND() → ES6 109
ARRAYVAR.FINDINDEX() → ES6 110
ARRAY.FROM() → ES6 110
ARRAY.OF() → ES6 110
ARRAY.FILL() → ES6 111
ARRAYVAR.INCLUDES() → ES7 111
ARRAYVAR.FLAT() → ES10 111
ARRAYVAR.FLATMAP() → ES10 112
COMPLETE ARRAY REFERENCE. 112
DATE OBJECTS 113
JAVASCRIPT DATE OUTPUT 113
CREATING DATE OBJECTS 113
DATE METHODS 114
DATE FORMATS 115
JAVASCRIPT DATE INPUT 115
JAVASCRIPT DATE OUTPUT 116
TIME ZONES 116
DATE INPUT - PARSING DATES 116
GET DATE METHODS 117
THE NOW() METHOD → ES5 117
THE GETTIME() METHOD 117
THE GETFULLYEAR() METHOD 117
THE GETMONTH() METHOD 117
THE GETDATE() METHOD 117
THE GETHOURS() METHOD 117
THE GETMINUTES() METHOD 117
THE GETSECONDS() METHOD 118
THE GETMILLISECONDS() METHOD 118
THE GETDAY() METHOD 118

5
UTC DATE METHODS 118
SET DATE METHODS 120
THE SETFULLYEAR() METHOD 120
THE SETMONTH() METHOD 120
THE SETDATE() METHOD 120
THE SETHOURS() METHOD 120
THE SETMINUTES() METHOD 121
THE SETSECONDS() METHOD 121
THE SETMILLISECONDS() METHOD 121
COMPARE DATES 121
MAP DATA-STRUCTURE → ES6 122
MAP CREATION 122
INITIALIZE A MAP WITH VALUES 122
ADD ITEMS TO A MAP 122
GET AN ITEM FROM A MAP BY KEY 122
MAP KEYS 122
DELETE AN ITEM FROM A MAP BY KEY 123
DELETE ALL ITEMS FROM A MAP 123
CHECK IF A MAP CONTAINS AN ITEM BY KEY 123
FIND THE NUMBER OF ITEMS IN A MAP 123
ITERATING OVER A MAP 123
CONVERT TO ARRAY 124
WEAKMAP 124
SET DATA-STRUCTURE → ES6 125
INITIALIZE A SET 125
INITIALIZE A SET WITH VALUES 125
ADD ITEMS TO A SET 125
CHECK IF AN ITEM IS IN THE SET 125
DELETE AN ITEM FROM A SET BY KEY 125
DETERMINE THE NUMBER OF ITEMS IN A SET 126
DELETE ALL ITEMS FROM A SET 126
ITERATE THE ITEMS IN A SET 126
CONVERT THE SET KEYS INTO AN ARRAY 126
RELATION WITH ARRAY OBJECTS 127
REMOVE DUPLICATE ELEMENTS FROM THE ARRAY 127
A WEAKSET 127
REFLECT OBJECT → ES6 128
STATIC METHODS 128
MATH OBJECT 131
MATH CONSTRUCTOR 131
MATH.ROUND() 131
MATH.POW() 131
MATH.SQRT() 131
MATH.ABS() 131
MATH.CEIL() 131
MATH.FLOOR() 132
MATH.SIN() 132
MATH.COS() 132
MATH.MIN() AND MATH.MAX() 132
MATH.RANDOM() 132
MATH.TRUNC() → ES6 132
MATH.CBRT() → ES6 133

6
MATH.SIGN() → ES6 133
MATH PROPERTIES (CONSTANTS) 133
RANDOM 134
A PROPER RANDOM FUNCTION 134
COMPARISON & LOGICAL OPERATORS 135
COMPARISON OPERATORS 135
LOGICAL OPERATORS 135
CONDITIONAL (TERNARY) OPERATOR 135
BINARY LOGICAL OPERATORS 136
COMPARING DIFFERENT TYPES 136
CONDITIONS 137
CONDITIONAL STATEMENTS 137
COMMON CODE BLOCKS IN SWITCH 138
SWITCHING DETAILS 139
STRICT COMPARISON 139
LOOPS 140
1. THE FOR LOOP 140
2. THE FOR/IN LOOP 141
3. THE FOR/OF LOOP → ES6 141
4. THE WHILE LOOP 141
5. THE DO/WHILE LOOP 142
COMPARING FOR AND WHILE 142
BREAK & CONTINUE 143
THE BREAK STATEMENT 143
THE CONTINUE STATEMENT 143
JAVASCRIPT LABELS 143
TYPE CONVERSION 144
THE DATA TYPE OF TYPEOF 144
THE CONSTRUCTOR PROPERTY 144
JAVASCRIPT TYPE CONVERSION 144
CONVERTING NUMBERS, BOOLEANS AND DATES TO STRINGS 144
CONVERTING BOOLEANS AND DATES TO NUMBERS 144
AUTOMATIC TYPE CONVERSION 144
AUTOMATIC STRING CONVERSION 145
JAVASCRIPT TYPE CONVERSION TABLE 145
BITWISE OPERATIONS 147
JAVASCRIPT USES 32 BITS BITWISE OPERANDS 147
BITWISE AND ( & ) 147
BITWISE OR ( | ) 147
BITWISE XOR ( ^ ) 147
JAVASCRIPT BITWISE NOT ( ~ ) 148
JAVASCRIPT (ZERO FILL) BITWISE LEFT SHIFT (<<) 148
JAVASCRIPT (SIGN PRESERVING) BITWISE RIGHT SHIFT (>>) 148
JAVASCRIPT (ZERO FILL) RIGHT SHIFT (>>>) 148
BINARY NUMBERS 148
CONVERTING DECIMAL TO BINARY 149
CONVERTING BINARY TO DECIMAL 149
REGULAR EXPRESSIONS 150
REGULAR EXPRESSION MODIFIERS 150

7
REGULAR EXPRESSION PATTERNS 150
USING STRING METHODS 152
USING THE REGEXP OBJECT 152
REGEXP OBJECT METHODS 153
REGEXP OBJECT PROPERTIES 153
ERRORS 154
THE JAVASCRIPT STATEMENTS TRY AND CATCH COME IN PAIRS. 154
OPTIONAL CATCH BINDING → ES10 154
JAVASCRIPT THROWS ERRORS 154
THE FINALLY STATEMENT 155
THE ERROR OBJECT 155
ERROR OBJECT PROPERTIES 155
ERROR NAME VALUES 156
USE STRICT → ES5 157
THE "USE STRICT" DIRECTIVE 157
DECLARING STRICT MODE 157
THE "USE STRICT"; SYNTAX 157
WHY STRICT MODE? 157
NOT ALLOWED IN STRICT MODE 157
FUTURE PROOF! 158
CLASSES → ES6 159
CLASS DEFINITION 159
METHODS 159
STATIC METHODS 159
PRIVATE CLASS VARIABLES → ES11 160
INHERITANCE 160
GETTERS AND SETTERS 161
KEY POINTS TO REMEMBER ABOUT CLASSES 163
MODULES → ES6 164
MODULE BASICS 164
EXPORT MODULES 164
IMPORT MODULES 165
MODULES PATH REFERENCES 166
AGGREGATING MODULES 166
WHAT DOES IMPORT ACTUALLY DO? 167
JS USE STATIC MODULE SYSTEM 168
HOW TO USE DYNAMIC MODULE SYSTEM 168
DYNAMIC IMPORT → ES10 169
RESOURCES: 169
1- MODULES 169
JAVASCRIPT ASYNC 170
1. CALLBACKS 170
2. ASYNCHRONOUS JAVASCRIPT 170
3. PROMISES → ES6 171
4. JAVASCRIPT ASYNC/AWAIT → ES8 178
PROXY → ES6 179
PROXY HANDLERS 179
STATIC METHODS 181
WEB GEOLOCATION API 182
EVENT LOOP: MICROTASKS AND MACROTASKS 183

8
EVENT LOOP 183
TASK 183
HOW JS ENGINE HANDLE TASKS: 184
MORE ABOUT MICROTASKS 186
MICROTASKS FOR USE CASES 186
JAVASCRIPT DEBUGGING 188
CODE DEBUGGING 188
JAVASCRIPT DEBUGGERS 188
JAVASCRIPT STYLE GUIDE & CODING CONVENTIONS 189
JAVASCRIPT CODING CONVENTIONS 189
NAMING CONVENTIONS 190
ACCESSING HTML ELEMENTS 191
FILE EXTENSIONS 191
USE LOWER CASE FILE NAMES 191
JAVASCRIPT BEST PRACTICES 193
AVOID GLOBAL VARIABLES 193
ALWAYS DECLARE LOCAL VARIABLES 193
DECLARATIONS ON TOP 193
INITIALIZE VARIABLES 193
NEVER DECLARE NUMBER, STRING OR BOOLEAN OBJECTS 193
DON'T USE NEW OBJECT() 193
BEWARE OF AUTOMATIC TYPE CONVERSIONS 194
USE === COMPARISON 194
USE PARAMETER DEFAULTS → ES6 194
END YOUR SWITCHES WITH DEFAULTS 194
AVOID USING EVAL() 194
JAVASCRIPT COMMON MISTAKES 195
ACCIDENTALLY USING THE ASSIGNMENT OPERATOR 195
MISUNDERSTANDING FLOATS 195
BREAKING A JAVASCRIPT STRING → ES5 195
MISPLACING SEMICOLON 195
BREAKING A RETURN STATEMENT 195
ACCESSING ARRAYS WITH NAMED INDEXES 196
ENDING DEFINITIONS WITH A COMMA → ES5 196
UNDEFINED IS NOT NULL 196
JAVASCRIPT PERFORMANCE (SPEED UP YOUR CODE) 198
REDUCE ACTIVITY IN LOOPS 198
REDUCE DOM ACCESS 198
REDUCE DOM SIZE 198
AVOID UNNECESSARY VARIABLES 198
DELAY JAVASCRIPT LOADING 198
JAVASCRIPT FORMS 200
JAVASCRIPT FORM VALIDATION 200
DATA VALIDATION 200
HTML CONSTRAINT VALIDATION 200
HTML DOM 203
WHAT IS THE DOM? 203
WHAT IS THE HTML DOM? 204
HTML DOM METHODS 205

9
THE DOM PROGRAMMING INTERFACE 205
HTML DOM DOCUMENT 206
THE HTML DOM DOCUMENT OBJECT 206
FINDING HTML OBJECTS 206
HTML DOM COLLECTIONS 208
THE HTMLCOLLECTION OBJECT 208
HTML HTMLCOLLECTION LENGTH 208
METHODS 208
HTML DOM NAVIGATION 210
DOM NODES 210
NODE RELATIONSHIPS 210
NAVIGATING BETWEEN NODES 211
CHILD NODES AND NODE VALUES 212
INNERHTML 212
DOM ROOT NODES 212
THE NODENAME PROPERTY 213
THE NODEVALUE PROPERTY 213
THE NODETYPE PROPERTY 214
HTML DOM NODE LISTS 215
THE HTML DOM NODELIST OBJECT 215
HTML DOM NODE LIST LENGTH 215
HTML DOM NODE LIST METHODS 215
THE DIFFERENCE BETWEEN AN HTMLCOLLECTION AND A NODELIST? 216
HTML DOM ELEMENTS (NODES) 218
CREATING NEW HTML ELEMENTS (NODES) 218
CREATING NEW HTML ELEMENTS - INSERTBEFORE() 219
REMOVING EXISTING HTML ELEMENTS 219
REMOVING A CHILD NODE 220
REPLACING HTML ELEMENTS 221
HTML DOM ELEMENTS 223
FINDING HTML ELEMENTS 223
HTML DOM - CHANGING HTML 226
CHANGING THE HTML OUTPUT STREAM 226
CHANGING HTML CONTENT 226
CHANGING THE VALUE OF AN ATTRIBUTE 227
CHANGING HTML STYLE – CHANGING CSS 227
HTML DOM STYLE OBJECT REFERENCE. 228
HTML DOM ANIMATION 229
A BASIC WEB PAGE 229
CREATE AN ANIMATION CONTAINER 229
STYLE THE ELEMENTS 229
ANIMATION CODE 230
CREATE THE ANIMATION USING JAVASCRIPT 230
HTML DOM EVENTS 232
REACTING TO EVENTS 232
HTML EVENT ATTRIBUTES 233
ASSIGN EVENTS USING THE HTML DOM 233
THE ONLOAD AND ONUNLOAD EVENTS 233

10
THE ONCHANGE EVENT 234
THE ONMOUSEOVER AND ONMOUSEOUT EVENTS 234
THE ONMOUSEDOWN, ONMOUSEUP AND ONCLICK EVENTS 235
MORE EXAMPLES 235
HTML DOM EVENT OBJECT REFERENCE. 236
HTML DOM EVENTLISTENER 237
THE ADDEVENTLISTENER() METHOD 237
SYNTAX 237
ADD AN EVENT HANDLER TO AN ELEMENT 237
ADD MANY EVENT HANDLERS TO THE SAME ELEMENT 238
ADD AN EVENT HANDLER TO THE WINDOW OBJECT 238
PASSING PARAMETERS 238
EVENT BUBBLING OR EVENT CAPTURING? 238
THE REMOVEEVENTLISTENER() METHOD 239
BROWSER SUPPORT 239
PREVENTDEFAULT EVENT METHOD 240
STOPPROPAGATION EVENT METHOD 240
STOPIMMEDIATEPROPAGATION EVENT METHOD 240
HTML DOM EVENT OBJECT REFERENCE. 241
BROWSER BOM 242
THE BROWSER OBJECT MODEL (BOM) 242
THE WINDOW OBJECT 242
WINDOW SIZE 242
OTHER WINDOW METHODS 242
WINDOW SCREEN 243
WINDOW SCREEN PROPERTIES 243
WINDOW LOCATION 244
WINDOW LOCATION PROPERTIES & METHODS 244
WINDOW HISTORY 245
WINDOW HISTORY METHODS 245
WINDOW NAVIGATOR 246
WINDOW NAVIGATOR PROPERTIES AND METHODS 246
WARNING !!! 246
POPUP BOXES 248
1. ALERT BOX 248
2. CONFIRM BOX 248
3. PROMPT BOX 248
TIMING EVENTS 248
1. THE SETTIMEOUT() METHOD 250
.2THE SETINTERVAL() METHOD 250
MORE EXAMPLES 250
COOKIES 252
WHAT ARE COOKIES? 252
CREATE A COOKIE WITH JAVASCRIPT 252
READ A COOKIE WITH JAVASCRIPT 252
CHANGE A COOKIE WITH JAVASCRIPT 253
DELETE A COOKIE WITH JAVASCRIPT 253
THE COOKIE STRING 253

11
JAVASCRIPT COOKIE EXAMPLE 253
WINDOW LOCALSTORAGE PROPERTY 256
WINDOW SESSIONSTORAGE PROPERTY 257
DIFFERENCES BETWEEN SESSIONSTORAGE, LOCALSTORAGE AND COOKIES 258
CONSOLE 259
• CONSOLE.ASSERT() 259
• CONSOLE.CLEAR() 259
• CONSOLE.COUNT() 259
• CONSOLE.COUNTRESET() 260
• CONSOLE.DEBUG() 260
• CONSOLE.DIR() 260
• CONSOLE.DIRXML() 260
• CONSOLE.ERROR() 261
• CONSOLE.GROUP() 261
• CONSOLE.GROUPCOLLAPSED() 262
• CONSOLE.INFO() 262
• CONSOLE.LOG() 262
• DIFFERENCE BETWEEN LOG() AND DIR() 262
• LOGGING OBJECTS 263
• CONSOLE.TABLE() 263
• CONSOLE.TIME() 265
• CONSOLE.TIMEEND() 265
• CONSOLE.TIMESTAMP() – NOT STANDARDIZED 265
• CONSOLE.TRACE() 265
• CONSOLE.WARN() 266
WHAT IS THE DIFFERENCE BETWEEN VIEWSTATE AND SESSIONSTATE? 267

12
13
Basics Information Before you Start
• Ascending (‫ )تصاعدي‬means smallest to largest, 0 to 9, and/or A to Z.
• Descending (‫ )تنازلي‬means largest to smallest, 9 to 0, and/or Z to A.
• A code block is a block of code between { and }.
• Lexical Scope: Static scope. The word lexical refers to the fact that
lexical scoping uses the location where a variable is declared within
the source code to determine where that variable is available
• Context Scope: Dynamic scope.

1
JavaScript
- JavaScript is an object-based scripting language which is lightweight
and cross-platform.
- It is used to create client-side dynamic pages. The programs in
JavaScript language are called scripts. The scripts are written in HTML
pages and executed automatically as the page loads. It is provided
and executed as plain text and does not need special preparation or
compilation to run.

External JavaScript Advantages


1. It separates HTML and code.
2. It makes HTML and JavaScript easier to read and maintain.
3. Cached JavaScript files can speed up page loads.

JavaScript and ECMA Script relation


- ECMA Script are like rules and guideline while JavaScript is a scripting
language used for web development.

Namespacing in JavaScript
- namespace is a unique name used for grouping the desired functions,
objects and properties. This improves modularity in the coding and
enables code reuse.

2
JavaScript Versions
- ECMAScript is the official name of the language. From 2015
ECMAScript is named by year (ECMAScript 2015).
- ECMAScript is often abbreviated to ES.

ECMAScript Editions

Official Name Description

ECMAScript 1 (1997) First Edition.

ECMAScript 2 (1998) Editorial changes only.

ECMAScript 3 (1999) Added Regular Expressions.


Added try/catch.

ECMAScript 4 Never released.

ECMAScript 5 (2009) Features are Marked with ES5 in the book.

ECMAScript 5.1 (2011) Editorial changes.

ECMAScript 6 (2015) Arrow Functions


Classes
Enhanced Object Literals
Template Strings
Destructuring Array & Object
Default, Rest & Spread
Let & Const
Iterators & for/of
Generators
Unicode
Modules & Module loaders
Map & Weakmap, Set & Weakset
Proxies
Symbols
Subclassable built-ins
Promises
Math, Number, String, Array & Object APIs
Binary and Octal Literals

3
Reflect API
Tail Calls

ECMAScript 7 (2016) Array.prototype.includes()


Exponentiation operator
ECMAScript 8 (2017) Async Functions
Shared memory and atomics.
Minor new features:
Object.values/Object.entries
String padding
Object.getOwnPropertyDescriptors()
Trailing commas in function
parameter lists and calls

ECMAScript 9 (2018) Asynchronous Iteration


Rest/Spread Properties
New regular expression features:
RegExp named capture groups
RegExp Unicode Property Escapes
RegExp Lookbehind Assertions
s (dotAll) flag for regular
expressions
Other new features:
Promise.prototype.finally()
Template Literal Revision

More details here

4
ECMAScript 2009 (ES5)
- ECMAScript 5 is also known as ES5 and ECMAScript 2009.
- ECMAScript 2009(ES5) introduced the following new features:
• The "use strict" Directive
• String.trim()
• Array methods
o Array.isArray()
o Array.forEach()
o Array.map()
o Array.filter()
o Array.reduce() & Array.reduceRight()
o Array.every()
o Array.some()
o Array.indexOf()
o Array.lastIndexOf()
• JSON.parse()
• JSON.stringify()
• Date Methods
o Date.now()
o Date.toISOString()
• Property Getters and Setters.
• Object Property Methods.
• Function.prototype.bind()

Syntactical Changes
• Property access [ ] on strings.
• Trailing commas in array and object literals.
• Multiline string literals.
"foo \
bar"
• Reserved words as property names.

JSON.parse()
- A common use of JSON is to receive data from a web server, used to
convert the text into a JavaScript object.
JSON.stringify()
- A common use of JSON is to send data to a web server. When
sending data to a web server, the data has to be a string.

Reserved Words as Property Names


- ECMAScript 5 allows reserved words as property names.

var obj = {name: "John", new: "yes"}

5
6
ECMAScript 2015 (ES6)
- ECMAScript 6 is also known as ES6 and ECMAScript 2015. Some
people call it JavaScript 6.
- ECMAScript 2015(ES6) introduced the following new features:

• Arrow Functions
• A new this scope
• Symbol Type
• Iterators
• Promises
• Generators
• let & const
• Classes
o Constructor
o Super
o Getters and setters
• Modules
o Importing modules
o Exporting modules
• Template Literals
• Default parameters
• The spread operator
• Enhanced Object Literals
o Simpler syntax to include variables
o Prototype
o super()
o Dynamic properties
• For-of loop
• Map & Set
• New String methods
• New Object methods
• Number Safety Checking Methods
• Number Type Checking Methods
• Array Elements Finding
• Destructuration Assignment
o Array Matching
o Object Matching
o Object Matching, Deep Matching
o Object And Array Matching, Default Values
o Parameter Context Matching

7
ECMAScript 2016 (ES7)
- ECMAScript 2016(ES7) introduced only two new features:
o Array.prototype.includes().
o Exponentiation operator.

8
ECMAScript 2017 (ES8)
- At the TC39 meeting in January 2017, the last feature of ECMAScript
2017, “Shared memory and atomics” .
- Major new features:
o Async Functions.
o Shared memory and atomics.
- Minor new features:
o Object.values/Object.entries.
o Object.getOwnPropertyDescriptors().
o String padding.
o Trailing commas in function parameter lists and calls.

9
ECMAScript 2018 (ES9)
- Major new features:
o Asynchronous Iteration.
o Rest/Spread Properties.
- New regular expression features:
o RegExp named capture groups.
o RegExp Unicode Property Escapes.
o RegExp Lookbehind Assertions.
o s_(dotAll) flag for regular expressions.
- Other new features:
o Promise.prototype.finally().
o Template Literal Revision.

10
ECMAScript 2019 (ES10)
- ES10 is the version of ECMAScript corresponding to the year 2019.
This version does not include as many new features as those that
appeared in ES6 (2015).
- The new JavaScript features in ES2019 are:
o Array.flat(), Array.flatMap().
o Object.fromEntries().
o String.trimStart(), String.trimEnd().
o Symbol Description.
o try/catch. Optional binding.
o JSON ⊂ ECMAScript.
o well-formed JSON.stringify.
o Stable Array.prototype.sort().
o New Function.toString()
o BigInt primitive type → Not Stable, will be in ES11.
o Dynamic import → Not Stable, will be in ES11.
o Standardized globalThis object.

11
ECMAScript 2020 (ES11)
- We’re going to review some of the latest features coming with
ES2020.
- Some of them are:
o Private Class Variables
o Promise.allSettled().
o String.prototype.matchAll
o Optional Chaining Operator
o Nullish Coalescing Operator
o Dynamic import
o BigInt primitive type

Optional Chaining Operator → ES11


- Long chains of property accesses can be error-prone, and checking
for property existence on each step turns into a deeply-nested
structure
let car = { }
//before ES11
let consumption = car.engine.consumption; // Uncaught TypeError: Cannot read property
'consumption' of undefined

//ES11
let consumption = car?.engine?.consumption //No error and consumption is undefined

- Optional chaining works on arrays or function calls too.


let array = [6]
let car1 = array?.[1] // undefined without throwing an error

Nullish Coalescing Operator → ES11


- A new operator was added to JavaScript. It came to cause a
discrepancy between JavaScript’s falsey value. We use the falsey
condition with the || operator. The falsey values are: 0, undefined,
null, false, NaN

12
- The new operator ?? only considered undefined and null, as falsey
values. Note that, different from the case above, the values of 0,
NaN, false are persisted even though a non-falsey value.

13
JavaScript Syntax
JavaScript Values
- Fixed values are called literals. Variable values are called variables.
Literals Variables
Numbers var x = 5;
Strings

JavaScript Statements
- A computer program is a list of "instructions" to be "executed" by a
computer. In a programming language, these programming
instructions are called statements. A JavaScript program is a list of
programming statements.
o The statements are executed, one by one, in the same order as
they are written.
o Semicolons separate JavaScript statements, semicolon is not
required, but highly recommended.
o JavaScript ignores multiple spaces, =‘value’ or = ‘value’
o One place you will find statements grouped together in code
blocks, inside curly brackets {...}, is in JavaScript functions.

JavaScript Expressions
- An expression is a combination of values, variables, and operators,
which computes to a value “an evaluation”.

JavaScript Identifiers
- All JavaScript variables must be identified with unique names.
- Can be short or descriptive names.
- the first character must be a letter, or an underscore (_), or a dollar
sign ($). Subsequent characters may be letters, digits, underscores,
or dollar signs.
- Numbers are not allowed as the first character, so JS easily
distinguish identifiers from numbers.

JavaScript is Case Sensitive


- LastName is not same lastname

14
JavaScript and Camel Case
- ways of joining multiple words:

Hyphens first-name NOT Allowed in JS

Underscore first_name

Upper Camel Case (Pascal Case) FirstName

Lower Camel Case firstName JS tend to this way

JavaScript Character Set


- uses the Unicode character set
- Complete Unicode Reference.

JavaScript Comments
1. Single line comments start with // → most common
2. Multi-line comments start with /* and end with */ → formal
documentation.
- Using comments to prevent execution of code.

15
JavaScript Global
- The JavaScript global properties and functions can be used with all
the built-in JavaScript objects.

JavaScript Global Properties

Property Description

Infinity A numeric value that represents positive/negative


infinity.

NaN "Not-a-Number" value.

undefined Indicates that a variable has not been assigned a value.

JavaScript Global Functions

Function Description

decodeURI() Decodes a URI

decodeURIComponent() Decodes a URI component

encodeURI() Encodes a URI

encodeURIComponent() Encodes a URI component

escape() Deprecated in version 1.5.


Use encodeURI() or encodeURIComponent() ins
tead

eval() Evaluates a string and executes it as if it was


script code

isFinite() Determines whether a value is a finite, legal


number

isNaN() Determines whether a value is an illegal


number

Number() Converts an object's value to a number

parseFloat() Parses a string and returns a floating point


number

parseInt() Parses a string and returns an integer

String() Converts an object's value to a string

16
unescape() Deprecated in version
1.5. Use decodeURI() or decodeURIComponent(
) instead

Functions or Methods?
- It makes sense to call the list above global functions rather
than global methods because the functions are called globally
and not any objects.
- Anyway, you can also call these functions methods, since they are
methods of the global object where they run. In a web browser,
the global object is the browser window. Then isNaN() is actually a
window method: window.isNaN().

encodeURI & encodeURIComponent


- URLs do not allow many special characters. However these special
characters are part of life, so URL encoding was invented.
- Both are used to encode 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.
The difference
• There aren't big differences, the unique difference is that
encodeURI() function encodes special characters, except: , / ? :
@ & = + $ # whereas encodeURIComponent() function
encodes special characters and in additional the characters
which encodeURI doesn't encode.
When and What to use
• If you're encoding a string to put in a URL component (a query
string parameter), you should use encodeURIComponent and if
you're encoding an existing URL, use encodeURI.

17
Uniform Resource Identifier (URI)
- A URI is a sequence of characters that identifies a logical or
physical resource. According to the specifications, resources do not
have to be accessible on the Internet. Examples of resources
include electronic documents, elevator door sensors.
- There are two types of URIs”:
1. Uniform Resource Locator (URL) – this type of URI begins by
stating which protocol should be used to locate and access the
physical or logical resource on a network. If the resource is a
web page, for example, the URI will begin with the protocol
HTTP. If the resource is a file, the URI will begin with the
protocol FTP or if the resource is an email address, the URI will
begin with the protocol mailto. It is important to remember that
URLs are not persistent. This means that if the resource’s
location changes, the URL also needs to change to point to the
resource’s new location.
2. Uniform Resource Name (URN) – this type of URI does not
state which protocol should be used to locate and access the
resource; it simply labels the resource with a persistent,
location-independent unique identifier. A URN will identify the
resource throughout its lifecycle and will never change. Each
URN has three components: the label “urn,” a colon and a
character string that serves as a unique identifier.

18
JavaScript Scope
- Scope determines the accessibility (visibility) of variables.
- In general terms, the scope will let us know at a given part of
code, what are the variables and functions that we can or cannot
access.
- In JavaScript there are two types of scope:
1. Local or Function scope.

2. Global scope.

3. Block scope

1. Local JavaScript Variables


• Variables declared within a JavaScript function, become LOCAL to
the function. They can only be accessed from within the function.
• So variables with the same name can be used in different
functions.
• Local variables are created when a function starts, and deleted
when the function is completed.
• Function arguments (parameters) work as local variables inside
functions.

2. Global JavaScript Variables


• A variable declared outside a function, becomes GLOBAL.
• All scripts and functions on a web page can access it.

3. Block Scope
• It is related to the variables declared using let and const.
Variables declared with var do not have block scope.
• Block scope tells us that any variable declared inside a block { },
can be accessed only inside that block and cannot be accessed
outside of it.

Scope Chain
- JavaScript engine also uses Scope to find variables.
- JavaScript engine tries to find the variable in local scope, if not
exist, it tries to check for the variable in the outer scope. If the
variable does not exist in the outer scope, it tries to find the variable
in the global scope.

19
- If the variable is not found in the global space as well, reference error
is thrown.

JavaScript Variables
- In JavaScript, objects and functions are also variables.

Automatically Global
- If you assign a value to a variable that has not been declared, it will
automatically become a GLOBAL variable.

Strict Mode → ES5


- All modern browsers support running JavaScript in "Strict Mode".
- In "Strict Mode", undeclared variables are not automatically global.

Global Variables in HTML


- In HTML, the global scope is the window object. All global variables
belong to the window object.

The Lifetime of JavaScript Variables


- The lifetime of a JavaScript variable starts when it is declared.
- Local variables are deleted when the function is completed.
- In a web browser, global variables are deleted when you close the
browser window (or tab).

20
Declaring (Creating) Variables
- Variables are containers for storing data values.
- After the declaration, the variable has no value “undefined”.
- It's a good programming practice to declare all variables at the
beginning of a script.

1. JavaScript Var
o You can declare many variables in one statement, start the
statement with var and separate the variables by comma or
span multiple lines.
o If you re-declare a JavaScript variable, it will not lose its
value.

2. JavaScript Let → ES6


o let and const keywords, provide Block Scope variables
(and constants) in JavaScript.
o Before ES2015, JavaScript had only two types of
scope: Global Scope and Function Scope.

JavaScript Block Scope


- Variables declared with the var keyword cannot have Block Scope.

{
var x = 2;
}
// x CAN be used here

- Variables declared inside a block {} can be accessed from outside the


block.
- Before ES2015 JavaScript did not have Block Scope.
- Variables declared with the let keyword can have Block Scope.
variables declared inside a block {} cannot be accessed from outside
the block.

{
let x = 2;
}
// x can NOT be used here

21
Redeclaring Variables
- Redeclaring a variable using the var keyword can impose problems.
Redeclaring a variable inside a block will also redeclare the variable
outside the block.
var x = 10;
// Here x is 10
{
var x = 2;
// Here x is 2
}
// Here x is 2

- Redeclaring a variable using the let keyword can solve this problem.
Redeclaring a variable inside a block will not redeclare the variable
outside the block.

var x = 10;
// Here x is 10
{
let x = 2;
// Here x is 2
}
// Here x is 10

- the variable declared in the loop does not redeclare the variable
outside the loop.

Function Scope
- Variables declared with var and let are quite similar when declared
inside a function.

Global Scope
- Variables declared with var and let are quite similar when declared
outside a block. They will both have Global Scope.

Global Variables in HTML

22
- In HTML, the global scope is the window object. Global variables
defined with the var keyword belong to the window object.
- Global variables defined with the let keyword do not belong to the
window object.

Redeclaring
- Redeclaring a JavaScript variable with var is allowed anywhere in a
program.
- Redeclaring a var variable with let, in the same scope, or in the
same block, is not allowed, vice versa same thing too.
- Redeclaring a let variable with let, in the same scope, or in the
same block, is not allowed.
- Redeclaring a variable with let, in another scope, or in another block,
is allowed.

Hoisting
- Variables defined with let are not hoisted to the top and using it
before declaring it will throw ReferenceError.

// you can NOT use carName here


let carName;

3. JavaScript Const → ES6


- Variables defined with const behave like let variables, except they
cannot be reassigned.

Block Scope
- Declaring a variable with const is similar to let when it comes
to Block Scope.

Assigned when Declared


- JavaScript const variables must be assigned a value when they are
declared.

Not Real Constants


- const does NOT define a constant value. It defines a constant
reference to a value. Because of this:

23
- If we assign a primitive value to a constant, we cannot change the
primitive value.
- You can change the properties of a constant object, but you can’t
reassign a constant object.

// You can create a const object:


const car = {type:"Fiat", model:"500", color:"blue"};

// You can change a property:


car.color = "red";

// You can add a property:


car.owner = "Johnson";

// ERROR
car = {type:"BMW", model:"EX60", color:"red"};

- You can change the elements of a constant array, by reassign,


remove or push an element. But you can NOT reassign a constant
array.

Redeclaring
- Redeclaring or reassigning an existing var or let variable to const, in
the same scope, or in the same block, is not allowed.
var x = 2; // Allowed
const x = 2; // Not allowed
{
let x = 2; // Allowed
const x = 2; // Not allowed
}

- Redeclaring or reassigning an existing const variable, in the same


scope, or in the same block, is not allowed.

{
const x = 2; // Allowed
const x = 3; // Not allowed
x = 3; // Not allowed
var x = 3; // Not allowed

24
let x = 3; // Not allowed
}

- Redeclaring a variable with const, in another scope, or in another


block, is allowed.

const x = 2; // Allowed

{
const x = 3; // Allowed
}

Hoisting
- Variables defined with const are not hoisted to the top. It cannot be
used before it is declared.
carName = "Volvo"; // You can NOT use carName here
const carName = "Volvo";

Temporal Dead Zone


- It is a behavior that occurs with variables declared
using let and const keywords. It is a behavior where we try to
access a variable before it is initialized.

25
JavaScript Hoisting
- Hoisting is JavaScript's default behavior of moving
declarations to the top.
- Hoisting applies to variable & function declarations.

JavaScript Declarations are Hoisted


- A variable can be used before it has been declared.

x = 5; // Assign 5 to x

elem = document.getElementById("demo");
elem.innerHTML = x; // Display x in the element

var x; // Declare x

- So JavaScript by default behavior, moving all declarations to the top


of the current scope (to the top of the current script or the current
function).
- Variables and constants declared with let or const are not hoisted.

JavaScript Initializations are Not Hoisted


- JavaScript only hoists declarations, not initializations.

var x = 5; // Initialize x

elem = document.getElementById("demo");
elem.innerHTML = x + " " + y; // Display x and y, result is “5 undefined”

var y = 7; // Initialize y

- Y will be undefined, this is because only the declaration (var y), not
the initialization (=7) is hoisted to the top.

Note - To avoid hoisting, you can run JavaScript in strict mode by using
“use strict” on top of the code.

Declare Your Variables At the Top !

26
JavaScript in strict mode does not allow variables to be used if they are not
declared.

Arithmetic Operators
Operator Description

+ Addition

- Subtraction

* Multiplication

** Exponentiation (ES2016) same as Math.pow(x,exp)

/ Division

% Modulus (Division Remainder)

++ Increment

-- Decrement

- The numbers are called operands, and the operation is defined by


an operator.

Operator Precedence
- the order in which operations are performed.
- Multiplication (*) and division (/) have higher precedence than
addition (+) and subtraction (-).
- When using parentheses (), the operations inside the parentheses
are computed first
- When many operations have the same precedence, they are
computed from left to right. L → R

Value Operator Description Example


20 () Expression grouping (3 + 4)

19 . Member person.name
19 [] Member person["name"]
19 () Function call myFunction()
19 new Create new Date()

27
17 ++ Postfix Increment i++
17 -- Postfix Decrement i--

28
16 ++ Prefix Increment ++i
16 -- Prefix Decrement --i
16 ! Logical not !(x==y)
16 typeof Type typeof x

15 ** Exponentiation (ES2016) 10 ** 2

14 * Multiplication 10 * 5
14 / Division 10 / 5
14 % Division Remainder 10 % 5

13 + Addition 10 + 5
13 - Subtraction 10 - 5

12 << Shift left x << 2


12 >> Shift right x >> 2
12 >>> Shift right (unsigned) x >>> 2

11 < Less than x<y


11 <= Less than or equal x <= y
11 > Greater than x>y
11 >= Greater than or equal x >= y
11 in Property in Object "PI" in Math
11 instanceof Instance of Object instanceof Array

10 == Equal x == y
10 === Strict equal x === y
10 != Unequal x != y
10 !== Strict unequal x !== y

9 & Bitwise AND x&y


8 ^ Bitwise XOR x^y
7 | Bitwise OR x|y
6 && Logical AND x && y
5 || Logical OR x || y
4 ?: Condition ? "Yes" : "No"

3 += Assignment x += y
3 /= Assignment x /= y
3 -= Assignment x -= y
3 *= Assignment x *= y
3 %= Assignment x %= y

29
3 <<= Assignment x <<= y
3 >>= Assignment x >>= y
3 >>>= Assignment x >>>= y
3 &= Assignment x &= y
3 ^= Assignment x ^= y
3 |= Assignment x |= y

2 yield Pause Function yield x


1 , Comma 5,6

Exponentiation Operator → ES7


- The exponentiation operator (**) raises the first operand to the
power of the second operand.
var z = 5 ** 2; // result is 25

30
Data Types
1. Primitive data type (immutable)

o string
o number
o BigInt → ES10
o boolean
o Symbol → ES6
o null → typeof “object”
o undefined→ typeof “undefined”

2. Complex data type

o Object
o function → typeof “function”

Object Types

o Object
o Date
o Array
o Map → ES6
o Set → ES6
o String
o Number
o Boolean

JavaScript a (Loosely) Dynamically Typed Language


- In a dynamically typed language, the type of a variable is checked
during run-time in contrast to statically typed language, where the
type of a variable is checked during compile-time.
- Dynamically means that the same variable can be used to hold
different data types.
- It also called variable typing.

Passed by Value & Passed by Reference.


- In JavaScript, primitive data types are passed by value and non-
primitive data types are passed by reference.
- (Object, Array) if assigned to a new variable will be assigned by
reference.

31
Note:
- An empty string has both a legal value and a type, still type of string.
- null value is used to represent no value or no object. It implies no
object or null string, no valid boolean value, no number and no array
object.
- undefined It’s a property of global object and means “no value”,
o Variable used in the code doesn't exist.
o Variable is not assigned to any value.
o Property doesn't exist.

32
Strings
- JavaScript strings are used for storing and manipulating text.
- A JavaScript string is zero or more characters written inside quotes.
- You can use quotes inside a string, as long as they don't match the
quotes surrounding the string.

Escape Character
- The solution to avoid this problem (using same quotes inside it), is to
use the backslash escape character.

Code Result Description

\' ' Single quote

\" " Double quote

\\ \ Backslash

- The 6 escape characters were originally designed to control


typewriters, teletypes, and fax machines. They do not make any
sense in HTML.

Code Result

\b Backspace

\f Form Feed

\n New Line

\r Carriage Return

\t Horizontal Tabulator

\v Vertical Tabulator

Breaking Long Code Lines


- For best readability, avoid code lines > 80 characters. If a JavaScript
statement does not fit on one line, the best place to break it is after
an operator.
- The \ method is not the preferred method to break up a code
line within a text string. It might not have universal support. Some
browsers do not allow spaces behind the \ character.

33
- A safer way to break up a string, is to use string addition.

document.getElementById("demo").innerHTML = "Hello " +


"Dolly!";

Strings Can be Objects


- Strings are primitive values but can be defined as objects with the
keyword new.

var firstName = new String("John");

- Not to use string object, for example on comparison will fail to


compare primitive string with object string or between two different
objects of strings.

Template literals → ES6


- It make multiline strings much simpler.
- Once a template literal is opened with the backtick (`), you just press
enter to create a new line, without special characters and it’s
rendered as-is, keep in your mind space is meaningful.

const string = `Hey


this

string
is awesome!`

String Interpolation → ES6


- Intuitive expression interpolation for single-line and multi-line strings.

var program = { name: "World!!" };


var message = `Hello ${program.name}`;

34
String Methods and Properties
- In JavaScript, methods and properties are also available to primitive
values, because JavaScript treats primitive values as objects when
executing methods and properties.
- the length property returns the length of a string.
- JavaScript counts positions from zero.

Finding a String in a String


1. indexOf(searchValue, start)
- returns the position of the first occurrence of a specified text in a
string.
- If start < 0 → index 0.
- If start > str.length → index str.length. Which means the end of
the search.

2. lastIndexOf(searchValue, start)
- returns the index of the last occurrence of a specified text in a string.
- The search will start at the specified position, or at the end if no start
position is specified and end the search at the beginning of the array.
- If start < 0 → index 0. Which means the end of the search.
- If start > str.length → index str.length.

- indexOf() & lastIndexOf() return -1 if the text is not found.

3. startsWith(searchValue, start) →ES6


- determines whether a string begins with the characters of a specified
string. Returns false or true.
- The start is optional, at which to begin searching. Defaults to 0.

4. endsWith(searchValue, length) →ES6


- determines whether a string ends with the characters of a specified
string. Returns false or true.
- length is optional, which means the length of string to search in.

35
5. includes(searchValue, start) →ES7
- Determines whether a string contains the characters of a specified
string. Returns false or true.
- The start is optional, at which to begin searching. Defaults to 0.

- All methods above, are case sensitive.

6. matchAll(regExp) →ES11
- A method returns an iterator of all results matching a string against
the regular expression, including capturing groups.
- Syntax: str.matchAll(regExp)

Searching for a String in a String


- The search(regExp) method searches a string for a specified value
and returns the position of the match or -1 if not found.
- If string passed, converted it to regExp.

Search vs indexOf ?
- The search(regExp) method can’t take a second start position
argument.
- The indexOf() method can’t take regular expressions.

Extracting String Parts


1. slice(start, end)
- extracts a part of a string and returns the extracted part in a new
string.
- end parameter “not included” and it’s optional. If you omit it, the
method will slice out from start value to the end of string.

36
- If a parameter is negative. It start to count from the end of string
with 0 and not include the start parameter, end parameter will be
included.

var str = "Apple, Banana, Kiwi";


var res = str.slice(-12, -6); // Banana

2. substring(start, end)
- it is similar to slice(), the difference is that substring() can’t
accept negative indexes. end not included too.
- If start is greater than end, it will swap them.

3. substr(start, length)
- it is similar to slice(), the difference is that the second parameter
specifies the length of the extracted part.
- If start is negative, it’s not included, the position counts from the
end of the string to the end with the length required.
- length is optional.

Replacing String Content


- the replace(regExp | subStr, newSubstr| function) method
replaces a specified value with another value in a string.
- The replace() method does not change the string it is called on it
and returns a new string.
- By default, the replace() method replaces only the first match.
- We can use a regular expression which is written without quotes.

var n = str.replace(/MICROSOFT/i, "W3Schools");

- To replace all matches, use a regular expression with a /g flag


(global match).
- We can use function to provide the new string and it will be invoked
each time there is a match.

37
Converting to Upper and Lower Case
- A string is converted to upper case with toUpperCase().
- A string is converted to lower case with toLowerCase().

The concat(valueToAddBtw, txtToConcat …) Method


- joins two or more strings.

var txt1 = "Hello";


var txt2 = "World";
var newString = txt1.concat(" ", txt2);

- It is strongly recommended that the assignment operators (+, +=) are used
instead of the concat() method.

The trim() Method → ES5


- The trim() method removes whitespace from both sides of a string.
- Not Working on IE 8 or lower.

All string methods return a new string. They don't modify the original string.
Formally said: Strings are immutable: Strings cannot be changed, only
replaced.

Extracting String Characters


- All are read only, doesn’t change the string.

38
1. charAt(position)
- returns the character at a specified index (position) in a string.
- If not found return an empty string.

2. charCodeAt(position)
- returns the unicode of the character at a specified index in a string, it
returns a UTF-16 code (an integer between 0 and 65535)
- If the position is out of bounds, the charCodeAt() method will return
a special not-a-number value printed as NaN.

3. Property access [ ] → ES5


- Allows property access [ ] on strings.

var str = "HELLO WORLD";


str[0]; // returns H

- Property access might be a little unpredictable:


• Not Working on IE 7 or earlier.
• It makes strings look like arrays (but they aren’t).
• If no character is found, [ ] returns undefined.
• str[0] = "A" gives no error (but doesn’t work!).

Repeating a string → ES6


- repeat(numberOfTimes) repeats the strings for the specified number
of times.

'Ho'.repeat(3) //HoHoHo

Converting a String to an Array


- A string can be converted to an array with the split(onWhatToSplit,
limit) method.
- onWhatToSplit can be a regExp or an array which will converted to
string.
- If the separator is omitted or there is no match with separator the
returned array will contain the whole string in index [0].
- If the separator is "", the returned array will be an array of single
characters.

var txt = "Hello"; // String

39
txt.split(""); // Split in characters

- limit is a non-negative integer limiting the number of pieces. It’s


optional.

Complete String Reference .

40
Numbers
- JavaScript has only one type of number. Numbers can be written
with or without decimals.
- Extra-large or extra small numbers can be written with scientific
(exponent) notation:
var x = 123e5; // 12300000
var y = 123e-5; // 0.00123

JavaScript Numbers are Always 64-bit Floating Point


- JavaScript numbers are always stored as double precision floating
point numbers, on IEEE 754 standard.

- This format stores numbers in 64 bits, where the number (the


fraction) is stored in bits 0 to 51, the exponent in bits 52 to 62, and
the sign in bit 63.
- It takes 8 bytes (64 bits) in a computer’s memory.

Precision
- Integers (numbers without a period or exponent notation) are
accurate up to 15 digits.
- The maximum number of decimals is 17, but floating point arithmetic
is not always 100% accurate.

Numeric Strings
- JavaScript strings can have numeric content. All arithmetic operators
treat string as numeric except (+).

var x = "100";
var y = "10";
var z = x - y; // z will be 90

- But adding (+) a number and a string, JavaScript will treat the
number as a string, it’s called concatenation.

41
NaN - Not a Number
- It’s a JavaScript reserved word indicating that a number is not a legal
number. typeof NaN is a Number.

var x = 100 / "Apple"; // x will be NaN

Infinity
- Infinity (or -Infinity) is the value JavaScript will return if you
calculate a number outside the largest possible number.
- Both are numbers.
- Division by (zero) also generates Infinity (or -Infinity).

Hexadecimal
- Hexadecimal is base 16. Decimal is base 10. Octal is base 8. Binary
is base 2.
- JavaScript interprets numeric constants as hexadecimal if they are
preceded by 0x.
var x = 0xFF; // x will be 255

- By default, JavaScript displays numbers as base 10 (decimals).


- But you can use the toString(base) method to output numbers
from base 2 to base 36.

var myNumber = 40;


myNumber.toString(10); // returns 40
myNumber.toString(32); // returns 18
myNumber.toString(16); // returns 28
myNumber.toString(8); // returns 50
myNumber.toString(2); // returns 101000

Numbers Can be Objects


- JavaScript numbers are primitive values created from literals.
- But numbers can also be defined as objects with the keyword new.
- Can’t compare object numbers with primitive numbers.

42
Number Methods
- JavaScript treats primitive values as objects when executing methods
and properties.
- If use literals numbers leave a space before “.” to avoid considering it
as decimal point or one of the following ways:

1..toString()
1 .toString() // space before dot
(1).toString()
1.0.toString()

The toExponential() Method


- toExponential(parameter) returns a string, with a number rounded
and written using exponential notation.
- A parameter defines the number of characters behind the decimal
point. It is optional.
- It will keep one digit on right. If parameter required less than original
decimal numbers it will round numbers on left.

var x = 99.656;
x.toExponential(2); // returns 9.97e+1
x.toExponential(4); // returns 9.9656e+1
x.toExponential(6); // returns 9.965600e+1
x.toExponential(); // returns 9.9656e+1

The toFixed() Method


- toFixed(numberOfDecimals) returns a string, with the number
written with a specified number of decimals, It will round the
number to fit with decimals required.
- numberOfDecimals start from 0 and if omitted it will be 0 too.
var x = 9.656;
x.toFixed(0); // returns 10
x.toFixed(2); // returns 9.66
x.toFixed(4); // returns 9.6560
x.toFixed(6); // returns 9.656000

The toPrecision() Method

43
- toPrecision(wholeNumLength) returns a string, with a number
written with a specified length.

var x = 9.656;
x.toPrecision(); // returns 9.656
x.toPrecision(1); // returns 1e+1 = 10
x.toPrecision(2); // returns 9.7
x.toPrecision(4); // returns 9.656
x.toPrecision(6); // returns 9.65600

The valueOf() Method


- valueOf() returns a number as a number.
- It is used internally in JavaScript to convert Number objects to
primitive values. No more than that.

All JavaScript data types have a valueOf() and a toString() method.

Converting Variables to Numbers


- These are global JavaScript methods and can be used on all
JavaScript data types.
- Empty strings convert to 0.
- If number can’t be converted, NaN is returned.

1. Number(value) Method.
- convert JavaScript variables to numbers.
- It can also convert a date to a number, it will returned the
milliseconds of date since 1.1.1970
- Spaces and strings (a-z) not allowed, return NaN.

2. parseInt(value, base) Method.


- parses a string and returns a whole number. Only the first number is
returned.
- Spaces and strings (a-z) are allowed.

parseInt("10 20 30"); // returns 10


parseInt("10 years"); // returns 10
parseInt("years 10"); // returns NaN

44
- base is Optional.

3. parseFloat(value) Method.
- parses a string and returns a whole number. Only the first number is
returned. It returns the number with decimal point if exist.
- Spaces and strings (a-z) are allowed.

4. The Unary + Operator


- The unary + operator can be used to convert a variable to a number.

var y = "5"; // y is a string


var x = + y; // x is a number

Number Safety Checking Methods → ES6


- ES6 added 2 new methods to the Number object:
1. The isInteger() Method
▪ The Number.isInteger(numberVar) method returns true if
the argument is an integer, false otherwise.

2. The isSafeInteger() Method


▪ A safe integer is an integer that can be exactly represented
as a double precision number.
▪ The Number.isSafeInteger(numberVar) method
returns true if the argument is a safe integer, false
otherwise.
▪ Safe integers are all integers from -(253 - 1) to +(253 - 1).

Number Properties

Property Description

MAX_VALUE Returns the largest number possible in


JavaScript

MIN_VALUE Returns the smallest number possible in


JavaScript

45
POSITIVE_INFINITY Represents infinity (returned on anyNum /
0)

NEGATIVE_INFINITY Represents negative infinity (returned on


-anyNum / 0)

NaN Represents a "Not-a-Number" value

- Number properties belongs to the JavaScript's number object


wrapper called Number. You can Not use it with variable or number
value val.MAX_VALUE.

New Number Properties → ES6


- ES6 added the following properties to the Number object

1. EPSILON for more precise comparison of floating point numbers.


2. MIN_SAFE_INTEGER
3. MAX_SAFE_INTEGER

var x = Number.EPSILON;
var x = Number.MIN_SAFE_INTEGER;
var x = Number.MAX_SAFE_INTEGER;

Number Type Checking Methods → ES6


- ES6 also added 2 new number methods:
1. The isFinite() Method
▪ The Number.isFinite(value) method return true if the
value is of the type Number and equates to a finite number.
Otherwise (Infinity or NaN) it returns false.
▪ Number.isFinite() is different from the
global isFinite() function that the global function converts
the tested value to a Number, then tests it.

2. The isNaN() Method


▪ The Number.isNaN(value) method returns true if the
argument is NaN. Otherwise it returns false.
▪ The global isNaN() function, converts the tested value to a
Number, then tests it.

46
▪ Number.isNaN() does not convert the values to a Number
and will not return true for any value that is not of the type
Number.

BigInt - Arbitrary precision integers → ES10


- BigInt is the 7th primitive type and It is an arbitrary-precision
integer. The variables can now represent 2⁵³ numbers and not just
max out at 9007199254740992.

10n === BigInt(10); // true

Complete Number Reference.

47
Booleans
- A JavaScript Boolean represents one of two values: true or false.
- The Boolean value of an expression is the basis for all JavaScript
comparisons and conditions.
- Everything With a "Value" is True.
- Everything Without a "Value" is False. Such as 0, -0 , empty
string “”, undefined, null, false and NaN.

The Boolean() Function


- You can use the Boolean() function to find out if an expression (or a
variable) is true.

Boolean(10 > 9) // returns true


10 > 9 // returns true

Booleans Can be Objects


- Booleans can also be defined as objects with the keyword new.

var y = new Boolean(false);

- Don’t use Boolean Objects, comparison not working with type (===)
and you can’t compare two boolean objects.

Complete Boolean Reference.

48
Implicit Type Coercion in JavaScript.
- Implicit type coercion in JavaScript is automatic conversion of
value from one data type to another. It takes place when the
operands of an expression are of different data types.

String coercion
- It takes place while using the ‘ + ‘ operator. When a number is added
to a string, the number type is always converted to the string type.
- Type coercion also takes place when using the ‘ - ‘ operator, but the
difference is that, a string is converted to a number and then
subtraction takes place.

Boolean Coercion
- It takes place when using logical operators, ternary operators, if
statements and loop checks.

Equality Coercion
- Equality coercion takes place when using ‘ == ‘ operator. As we have
stated before, the ‘ == ‘ operator compares values and not types.
- While the above statement is a simple way to explain == operator,
it’s not completely true, the reality is that while using the ‘==’
operator, coercion takes place. The ‘==’ operator, converts both the
operands to the same type and then compares them.
- Coercion does not take place when using the ‘===’ operator. Both
operands are not converted to the same type in the case of ‘===’
operator.

49
Symbol → ES6
- Unique and immutable data type to be used as an identifier for
object properties. Symbol can have an optional description.
- Same global symbol, but not locally.
- Symbols are guaranteed to be unique. Even if we create many
symbols with the same description, they are different values.

Create a symbol
- To create a new primitive symbol, you write Symbol(description)
with an optional string as its description.
let sym1 = Symbol();
let sym2 = Symbol('foo');

Shared symbols in the global symbol registry


- To create symbols available across files and even across realms:
o Symbol.for(key) method searches for existing symbols in
symbol registry with the given key and returns it if found.
Otherwise a new symbol gets created in the global symbol
registry with this key.
Symbol.for('bar') === Symbol.for('bar'); // true
Symbol('bar') === Symbol('bar'); // false

o Symbol.keyFor(sym) method retrieves a shared symbol key


from the global symbol registry for the given symbol.
const globalSym = Symbol.for('foo'); // global symbol
console.log(Symbol.keyFor(globalSym));

“Hidden” properties
- Symbols allow us to create “hidden” properties of an object, that
no other part of code can accidentally access or overwrite.
let user = { // belongs to another code
name: "John"
};

let id = Symbol("id");

50
user[id] = 1;

Symbols in a literal
- If we want to use a symbol in an object literal {...}, we need
square brackets around it.
let id = Symbol("id");
let user = {
name: "John",
[id]: 123 // not "id: 123"
};

Symbols are skipped by for…in


- Symbolic properties do not participate in for/in loop. In addition
to Object.keys().

Finding symbol properties on objects


- Object.getOwnPropertySymbols(objVar) method returns an array of
symbols on a given object.

Display symbol
- It’s not converted to string automatically, you should use
symbolVar.toString().

Symbol Description → ES10


- There are a new Symbol description accessor, when you create
a Symbol you can provide a string as a description, in ES10 there
is an accessor to this property.
const symbol1 = Symbol("description");
console.log(symbol.toString()); //'Symbol(description)'

const symbol2 = Symbol("description");

51
console.log(symbol.description); // description

Symbol Reference

52
Functions
- It is a block of code designed to perform a particular task.
- Why Functions? You can reuse code.
- A programming language is said to have First-class functions
(citizen) when functions in that language are treated like any other
variable. In JavaScript, a function can be passed as an argument to
other functions, can be returned by another function and can be
assigned as a value to a variable.

JavaScript Function Syntax


- You can use a function declaration or a function expression or
function constructor.
1. A JavaScript function is defined with the function keyword, followed
by a name, followed by parentheses ().
function myFunction(a, b) {
return a * b;
}

2. A JavaScript function can also be defined using an expression. A


function expression can be stored in a variable. It’s called
anonymous function.

var x = function (a, b) {return a * b};

3. Functions can also be defined with a built-in JavaScript function


constructor called Function().
var myFunction = new Function("a", "b", "return a * b");

- A function definition can have only one reference variable as its


function name.
var foo = function Bar(){
return 7;
};
typeof Bar(); //Uncaught ReferenceError: Bar is not defined

- Function names have same rules as variable names.


- The parentheses may include parameters separated by commas:
(parameter1, parameter2, ...).
- The code to be executed, is placed inside curly brackets: {}

53
- Accessing a function without () will return the function definition
instead of the function result which done by ().
- Because of Hoisting function can be called before declaration.

- Semicolons are used to separate executable JavaScript statements.


Since a function declaration is not an executable statement, it is not
common to end it with a semicolon.
- The expression function ends with a semicolon because it is a part
of an executable statement.

Function Parameters & Arguments


- Function parameters are the names listed in the function definition.
- Function arguments are the real values passed to (and received by)
the function when it is invoked.

o Parameter Rules
- JavaScript function definitions don’t specify data types for
parameters.
- JavaScript functions don’t perform type checking on the passed
arguments.
- JavaScript functions don’t check the number of arguments
received.

o Parameter Context Matching → ES6


- Intuitive and flexible destructuring of Arrays and Objects into
individual parameters during function calls.

function f ([ name, val ]) {


console.log(name, val)
}
function g ({ name: n, val: v }) {
console.log(n, v)
}
function h ({ name, val }) {
console.log(name, val)
}
f([ "bar", 42 ])

54
g({ name: "foo", val: 7 })
h({ name: "bar", val: 42 })

o Arguments
- It’s local variables are created when a function starts, and deleted
when the function is completed.
- The arguments.length property returns the number of arguments
received when the function was invoked.
- JavaScript arguments are passed by value: The function only gets to
know the values, not the argument's locations.
- Changes to arguments aren’t visible (reflected) outside the
function.

Converting arguments to an Array


- arguments is not an array, it is only array-like. It has a
property length and you can access its elements via indices in square
brackets. You cannot, however, remove elements or invoke any of
the array methods on it. Thus, you sometimes need to
convert arguments to an array, which is what the following function
does.

function toArray(arrayLikeObject) {
return Array.prototype.slice.call(arrayLikeObject);
}

Default, Rest and Spread Parameters → ES6


o Parameter Defaults
- If a function is called with missing arguments (less than declared),
the missing values are set to: undefined
- Sometimes this is acceptable, but sometimes it is better to assign a
default value to the parameter.

function myFunction(x, y = 10) {


// y is 10 if not passed or undefined
return x + y;
}

o Rest Parameters

55
- Using the rest parameter syntax, we can create functions that can
take a variable number of arguments. Any number of arguments will
be converted into an array using the rest parameter.
- It also helps in extracting all or some parts of the arguments.
- Rest parameter can be used by applying three dots (...) before the
parameters, should be the last one of the arguments in the function.
function f (x, y, ...a) {
return (x + y) * a.length
}
f(1, 2, "hello", true, 7) === 9

o Spread Parameters
function f(x, y, z) {
return x + y + z;
}
// Pass each elem of array as argument
f(...[1,2,3]) == 6

o Key differences between rest parameter and spread operator:


- Rest parameter is used to take a variable number of arguments and
turns into an array while the spread operator takes an array or an
object and spreads it.
- Rest parameter is used in function declaration whereas the spread
operator is used in function calls.

JavaScript Function Invocation “call”


- It is common to use the term "call a function" instead of "invoke a
function".

function myFunction(a, b) {
return a * b;
}
myFunction(10, 2); // Will return 20

- The function above does not belong to any object. But in JavaScript
there is always a default global object.
- In HTML the default global object is the HTML page itself.

56
- In a browser the page object is the browser window. myFunction()
and window.myFunction() is the same function.

Self-Invoking Functions
- Function expressions can be made "self-invoking". It is invoked
(started) automatically, without being called.
- It is called IIFE (immediately invoked function expression,
pronounced “iffy”).
- Function expressions will execute automatically if the expression is
followed by ().
- This function is actually an anonymous self-invoking
function (function without name).

(function () {
var x = "Hello!!"; // I will invoke myself
})();

Functions Can Be Used as Values OR as Expression


var x = myFunction(4, 3) * 2;

Functions are Objects


- The typeof operator in JavaScript returns "function" for functions.
But, JavaScript functions can best be described as objects.

function myFunction(a, b) {
return arguments.length;
}

Arrow Functions → ES6


- Arrow functions allow us to write shorter function syntax.

// ES5
var x = function(x, y) {
return x * y;
}

// ES6
const x = (x, y) => x * y; //arrow function

57
- It gets shorter! If the function has only one statement and the
statement returns a value, you can remove the
brackets and the return keyword.

hello = () => "Hello World!";

- If you have parameters, you pass them inside the parentheses. But if
you have only one parameter, you can skip the parentheses as well.

hello = val => "Hello " + val;

- In regular function expressions, the this keyword always refers to


the object that is calling the function. The this keyword inside an
arrow function, does not refer to the object calling it. It rather
inherits its value from the parent scope.
- Arrow functions don’t have their own this. They are not well suited
for defining object methods and callback function with dynamic
content.
- Arrow functions are not hoisted. They must be defined before they
are used.
- Using const is safer than using var, because a function expression is
always constant value.
- Arrow functions are only callable and not constructible (can’t defined
a constructor with arrow function).
- There is No arguments property of arrow function.
- Explain this here

Function Return
- When JavaScript reaches a return statement, the function will stop
executing.
- Functions often compute a return value. The return value is
"returned" back to the "caller".

Function Call
- In JavaScript all functions are object methods (belong to Object or
Global Object).
- With call(thisArg, args...), an object can use a method belonging
to another object.
- A method allows an object to use the method (function) of another
object.

var person = {

58
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var person1 = {
firstName:"John",
lastName: "Doe"
}

person.fullName.call(person1); // Will return "John Doe"

- It can accept arguments


var person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + "," + city + "," + country;
}
}
var person1 = {
firstName:"John",
lastName: "Doe"
}
person.fullName.call(person1, "Oslo", "Norway");

JavaScript Function Apply


- The apply(thisArg, [argsArray]) method is similar to
the call() method.

var person = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var person1 = {
firstName: "Mary",
lastName: "Doe"

59
}
person.fullName.apply(person1); // Will return "Mary Doe"

- It can accept arguments


var person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + "," + city + "," + country;
}
}
var person1 = {
firstName:"John",
lastName: "Doe"
}
person.fullName.apply(person1, ["Oslo", "Norway"]);

JavaScript Function Bind → ES5


- bind(thisArg, args...) method returns a new function, where the
value of “this” keyword will be bound to the owner object, which is
provided as a parameter.
- The bind(thisArg, args...) method creates a new function that,
when called, has its this keyword set to the provided value, with a
given sequence of arguments preceding any provided when the
new function is called. It’s called partial function application.
- It creates a new bound function, which is an exotic (‫)غريب‬
function object (a term from ECMAScript 2015) that wraps the
original function object. You need to call it after that, calling the
bound function generally results in the execution of its wrapped
function.
const module = {
x: 42,
getX: function() {
return this.x;
}
};

const unboundGetX = module.getX;


console.log(unboundGetX()); // The function gets invoked at the global scope

60
// expected output: undefined

const boundGetX = unboundGetX.bind(module);


console.log(boundGetX());
// expected output: 42

The Difference Between call(), apply() and bind()


- The difference is call() method takes arguments separately. But
apply() method takes arguments as an array.
- bind() used when you want that function to be called later with a
certain context, useful in events. Use call() or apply() when you
want to invoke the function immediately, and modify the context.

JavaScript Closures
- Closures is an ability of a function to remember the variables and
functions that are declared in its outer scope.
- Global variables can be made local with closures.
- A closure gives you access to an outer function’s scope from an
inner function.
- To use a closure, define a function inside another function and
expose it. To expose a function, return it or pass it to another
function.
- Let’s understand closures by example.
function randomFunc(){
var obj1 = { name: "Vivian", age: 45 };

return function(){
console.log(obj1.name + " is "+ "awesome"); // Has access to obj1 even when the
randomFunc function is executed
}
}

var initialiseClosure = randomFunc(); // Returns a function

initialiseClosure(); //Vivian is awesome

61
- The function randomFunc() gets executed and returns a function
when we assign it to a variable:
var initialiseClosure = randomFunc();

- The returned function is then executed when we invoke


initialiseClosure:
initialiseClosure();

- The line of code above outputs “Vivian is awesome” and this is


possible because of closure.
- When the function randomFunc() runs, it sees that the returning
function is using the variable obj1 inside it:
console.log(obj1.name + " is "+ "awesome");

- Therefore randomFunc(), instead of destroying the value of obj1


after execution, saves the value in the memory for further
reference. This is the reason why the returning function is able to
use the variable declared in the outer scope even after the
function is already executed.
- This ability of a function to store a variable for further reference
even after it is executed, is called Closure.
- A closure is a function having access to the parent scope, even after
the parent function has closed.

New Function.toString() → ES10


- The toString() method returns a string representing the source
code of the function. In ES6 when toString was invoked on a
function it would return string representation of that function
depending on ECMAScript engine. When possible it would return
the source code, otherwise - a standardized placeholder.
this.fruits = [];
function buyFruits(fruit){
this. fruits = [...this.fruits, fruit];
}
console. log(buyFruits.toString());
/* function buyFruits(fruit){
this. fruits = [...this.fruits, fruit];
} */

Currying in JavaScript

62
- Currying is an advanced technique to transform a function of
arguments n, to n functions of one or less arguments.
- For Example, if we have a function f(a, b) , then the function after
currying, will be transformed to f(a)(b).
- By using the currying technique, we do not change the
functionality of a function, we just change the way it is invoked.
- Currying doesn’t call a function. It just transforms it.
function multiply(a, b){
return a*b;
}

function currying(fn){
return function(a){
return function(b){
return fn(a, b);
}
}
}

var curriedMultiply = currying(multiply);

multiply(4, 3); // Returns 12

curriedMultiply(4)(3); // Also returns 12

- It’s useful if you want a fixed arguments, and remaining one will
be provided as needed. In other words “partially applied function”
or “partial” for short.

Good Reference for currying

63
Void Operator
- The void operator evaluates the given expression and then
returns undefined.

Syntax
- void expression
Description
- This operator allows evaluating expressions that produce a value into
places where an expression that evaluates to undefined primitive
value, usually using "void(0)" (which is equivalent to "void 0"). In
these cases, the global variable undefined can be used.
- It should be noted that the precedence of the void operator should be
taken into account and that parentheses can help clarify the
resolution of the expression following the void operator:
void 2 == '2'; // (void 2) == '2', returns false
void (2 == '2'); // void (2 == '2'), returns undefined

- When using an immediately-invoked function expression, void can be


used to force the function keyword to be treated as an expression
instead of a declaration.

void function iife() {


console.log("Executed!");
}();
// Output: "Executed!"

- When a browser follows a javascript: URI, it evaluates the code in


the URI and then replaces the contents of the page with the returned
value, unless the returned value is undefined. The void operator can
be used to return undefined:

<a href="javascript:void(0);">
Click here to do nothing
</a>

- There is side effects by returning the result of a function call that


previously returned nothing. To be safe, when the return value of a
function is not intended to be used, it can be passed to the void
operator to ensure that (for example) changing APIs do not cause
arrow functions' behaviors to change.

button.onclick = () => void doSomething();

64
Iterators → ES6

Iterables
- A value is considered iterable if it has a method whose key is the
symbol Symbol.iterator that returns a so-called (‫ )ما يسمى ب‬iterator.
- Some of the built-in data structure that use iterable are:
o Arrays
o Strings
o Maps
o Sets
o arguments → array-like

Iterators
- Object that knows how to access items from a collection one at a
time, while keeping track of its current position within that sequence.
- An iterator is any object which implements the Iterator protocol by
having a next() method. Next method returns an object with two
properties:
▪ Value
The next value in the iteration sequence.
▪ Done
true if the last value in the sequence has already been
consumed, false, otherwise.

Making objects iterable


- We need to implement a method called Symbol.iterator. We will
use computed property syntax to set this key.

const customIterable = {
[Symbol.iterator]() {
let counter = 0;
return {
next() {

65
if (counter < 5) {
counter++;
return { done: false, value: counter };
} else {
return { done: true, value: undefined };
}
}
}
}
}

let iterator = customIterable[Symbol.iterator]();


console.log(iterator.next()); //{value: 1, done: false}

- Once created, an iterator object can be iterated explicitly by


repeatedly calling next(). Iterating over an iterator is said to
consume the iterator, because it is generally only possible to do once.
After a terminating value has been yielded additional calls
to next() should simply continue to return {done: true}.
- While it is easy to imagine that all iterators could be expressed as
arrays, this is not true. Arrays must be allocated in their entirety,
but iterators are consumed only as necessary. Because of this,
iterators can express sequences of unlimited size, such as the range
of integers between 0 and Infinity.

Iterators that are iterable


- if the iterable and the iterator are the same object:

const iterable = {
[Symbol.iterator]() {
return this;
},
next() {
if (index < args.length) {
return { value: args[index++] };
} else {
return { done: true };
}

66
},
};

- Even if the original iterable and the iterator are not the same object,
it is still occasionally useful if an iterator has the following method
(which also makes it an iterable):
[Symbol.iterator]() {
return this;
}

- Why is it useful if an iterator is also an iterable? For/of only


works for iterables, not for iterators.

var foo = {
[Symbol.iterator]: () => ({
items: ['p', 'o', 'n', 'y', 'f', 'o', 'o'],
next: function next () {
return {
done: this.items.length === 0,
value: this.items.shift()
}
}
})
}

- To iterate over iterables, we can use for/of, the spread operator


or Array.from.

Reference To Iterators

67
Generators → ES6
- In normal Function the only way to exist it, is by returning from it
or throwing an error. If you call the function again, it will begin the
execution from the top again.
- In contrast, a generator is a function that can stop midway and
then continue from where it stopped.
- Inside the function body, we don’t have a return. Instead, we have
another keyword yield. It’s an operator with a generator yields
“returns” the value specified after it and then pause itself.
- In JavaScript, a generator is a function which returns an object, you
can call next() on it. Every invocation of it will return an object:

{
value: Any,
done: true|false
}

- The value property will contain the value. The done property is
either true or false.
- We can also return from a generator. However, return sets
the done property to true, after that the generator cannot generate
any more values.
- Remember that every function implicitly returns undefined if no
return statement is provided when it’s finished.

{ value: undefined, done: true}

- Return in a generator functions make done true with a value, but


yield make done false with a value.

Generator functions
- Generator function identified by the function* keyword. You can
have a space between * and function.

function * generatorFunction() {
console.log('This will be executed first.');
yield 'Hello, ';
console.log('I will be printed after the pause');
yield 'World!';
}
const generatorObject = generatorFunction();

68
- Creating object from that function. the generator
function always returns a generator object. The generator object is
an iterator. So you can use it in for/of loops or other functions
accepting an iterable.
- we call the next() method on the generatorObject. With this call, the
generator begins executing.

console.log(generatorObject.next().value); // Hello,

- we call next() again. This time the generator wakes up and begin
executing from where it left.

console.log(generatorObject.next().value); // World!

- we again invoke next(). This time there are no more lines to


execute. The generator returns an object.

{ value: undefined, done: true}

- Or using for/of
for(let value of generatorObject) {
console.log(value); // Hello, then World!
}

- For/of iteration ignores the last value, when done: true. This is how
for loops works.

function* f(…) or function *f(…)?


- Both syntaxes are correct.

Generator composition
- How would you call generator from another generator function?
- ECMAScript 6 has the operator yield* for making recursive generator
calls.
function* bar() {
yield 'x';
yield* foo(); // another generator function
yield 'y';
}

- The operand of yield* does not have to be a generator object, it can


be any iterable.
yield* ['of', 'yielded'];

69
“yield” is a two-way street
- Until this moment, generators were similar to iterable objects, with a
special syntax to generate values. But in fact they are much more
powerful and flexible.
- That’s because yield is a two-way street: it not only returns the
result to the outside, but also can pass the value inside the
generator.
- To do so, we should call generator.next(arg), with an argument.
That argument becomes the result of yield.

function* gen() {
// Pass a question to the outer code and wait for an answer
let result = yield "2 + 2 = ?"; // (*)

alert(result);
}

let generator = gen();

let question = generator.next().value; // <-- yield returns the value // "2 + 2 = ?"

generator.next(4); // --> pass the result into the generator //4

1. The first call generator.next() should be always made without an


argument (the argument is ignored if passed). It starts the execution
and returns the result of the first yield "2+2=?". At this point the
generator pauses the execution, while staying on the line (*).
2. Then, as shown above, the result of yield gets into
the question variable in the calling code.
3. On generator.next(4), the generator resumes and 4 gets in as the
result: let result = 4.

yield binds loosely


- yield binds very loosely, so that we don’t have to put its operand in
parentheses.

yield a + b + c;

- As a consequence, you have to put yield in parentheses if you want


to use it as an operand.

70
console.log('Hello' + (yield)); // OK
console.log('Hello' + (yield 123)); // OK

- You do not need parens if yield is a direct argument in a function or


method call.

foo(yield 'a', yield 'b');

- You also don’t need parens if you use yield on the right-hand side of
an assignment.

const input = yield;

Using generators for iterables


- We can use a generator function for iteration by providing it
as Symbol.iterator without need to next() method.

let range = {
from: 1,
to: 5,

*[Symbol.iterator]() {
// a shorthand for [Symbol.iterator]: function*()
for(let value = this.from; value <= this.to; value++) {
yield value;
}
}
};

Uses of Generators
- There are many awesome use cases of generators.
1. Implementing Iterables
o When you implement an iterator, you have to manually
make an iterator object with a next() method. Also, you
have to manually save the state. Using generator will avoid
these issues.

2. Better Async functionality


o Code using promises and callbacks.

71
3. Infinite Data Streams
o It’s possible to create generators that never end.

function * naturalNumbers() {
let num = 1;
while (true) {
yield num;
num = num + 1
}
}
const numbers = naturalNumbers();
console.log(numbers.next().value) // 1
console.log(numbers.next().value) // 2

4. Generators as observers
o Generators can also receive values using
the next(val) function and it receives those values via
yield. Then the generator is called an observer since it
wakes up when it receives new values.

function* dataConsumer() {
console.log('Started');
console.log(`1. ${yield}`); // (A)
console.log(`2. ${yield}`);
return 'result';
}
const genObj = dataConsumer();
genObj.next();
// Started
// {value: undefined, done: false}
genObj.next('a');
// 1. a
//{value: undefined, done: false}
genObj.next('b');
// 2. b
//{value: "result", done: true}

72
o Unfortunately, next() is asymmetric, but that can’t be
helped: It always sends a value to the currently
suspended yield, but returns the operand of the
following yield.
o When using a generator as an observer, it is important to
note that the only purpose of the first invocation of next()
is to start the observer. It is only ready for input afterwards,
because this first invocation advances execution to the
first yield. Therefore, any input you send via the
first next() is ignored.

function* gen() {
// (A)
while (true) {
const input = yield; // (B)
console.log(input);
}
}
const obj = gen();
obj.next('a'); // NO OUTPUT
obj.next('b'); // b

Advantages of Generators
1. Lazy Evaluation
o Lazy Evaluation is an evaluation model which delays the
evaluation of an expression until its value is needed. That is,
if we don’t need the value, it won’t exist. It is calculated as
we demand it. Look Infinite Data Streams Example above.

2. Memory Efficient
o A direct consequence of Lazy Evaluation is that generators
are memory efficient. We generate only the values that are
needed. With normal functions, we needed to pre-generate
all the values and keep them around in case we use them
later.

Disadvantages of Generators
1. Generator objects are one-time access only.

73
o Once you’ve exhausted all the values, you can’t iterate over
it again. To generate the values again, you need to make a
new generator object.

2. Generator objects do not allow random access like with arrays.


o Since the values are generated one by one, accessing a
random value would lead to computation of values till that
element. Hence, it’s not random access.

74
Objects
- In JavaScript, objects are king. If you understand objects, you
understand JavaScript.
- Objects are variables, but can contain many values (unordered
properties).
- The values are written as name:value pairs (name and value
separated by a colon).
- JavaScript objects are containers for named values called properties
or methods.
- In JavaScript, almost "everything" is an object.
- Booleans, Numbers, Strings can be objects.
- Dates, Math, Regular expressions, Arrays, Functions, Objects, Maps,
Sets are always objects.
- Comparing two JavaScript objects will always return false.

Object (Create) Definition


- There are different ways to create new objects:

1. using an object literal and it’s the easiest way.

▪ An object literal is a list of name:value pairs inside curly braces


{}.
▪ define and create an object in one statement.

var person = {
firstName: "John",
lastName: "Doe",
age: 50,
eyeColor: "blue"
};

2. with the keyword new.

var person = new Object();


person.firstName = "John";
person.lastName = "Doe";
person.age = 50;
person.eyeColor = "blue";

75
3. Object.create(anyObject) → ES5
- Creates a new object, using an existing object as the
prototype of the newly created object. Return new object.
- Use it when you want to choose prototype object to
inherit to, without the need to define constructor. It’s a
way of “inheritance”.

JavaScript Objects are Mutable


- Object are mutable: object state can be modified after it is created.
- Objects are addressed by reference, not by value.

var x = person; // This will not create a copy of person object.

- Both x and person are the same object. Any change to one of them
will affect the other one.
var person = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"}

var x = person;
x.age = 10; // This will change both x.age and person.age

Object Properties
- The name:values pairs in JavaScript objects are called properties.
- Object properties can be primitive values, other objects and
functions.
- Properties can usually be changed, added and deleted, but some are
read only.
- You can access object properties in the following ways:
1. objectName.propertyName
2. objectName["propertyName"]
3. objectName[expression] // x = "age"; person[x]

- Square brackets also allow you to compute the key of a property.


- You can add new properties to an existing object by simply giving it a
value.

person.nationality = "English";

Delete Object Properties

76
- The delete keyword deletes a property (own key) from an object, the
delete operator doesn’t delete prototype property.

delete person.age; // or delete person["age"];

- It deletes both the value of the property and the property itself. After
deletion, the property cannot be used before it is added back again.
- It is designed to be used on object properties. It has NO effect on
variables or functions.
- It should not be used on predefined JavaScript object properties,
it can crash your application.

Property Attributes
- Each property in the object have a name. In addition they also have a
value and other attributes are: enumerable, configurable, and
writable.
- All attributes can be read, but only the value attribute can be
changed.
- ECMAScript 5 has methods for both getting and setting all property
attributes.

Changing Meta Data → ES5


- ES5 allows the following property meta data to be changed:

writable : true

- true the value associated with the property may be changed with
an assignment operator.
Defaults to true.

enumerable: true

- true shows property up during enumeration of the properties on the


corresponding object.
Defaults to false.

configurable: true

- true this property descriptor may be changed and the property may be
deleted from the corresponding object.
Defaults to false.

Object.defineProperty(person, "language", {writable:false});

77
Prototype Properties
- JavaScript objects inherit the properties of their prototype.
- The delete keyword does not actually delete inherited properties, but
if you delete a prototype property, it will affect all objects inherited
from the prototype.

Enhanced Object Literals → ES6


Property Shorthand → ES6
- Shorter syntax for common object property definition idiom.

//ES5
var x = 0, y = 0;
obj = { x: x, y: y };
//EC6
var x = 0, y = 0
obj = { x, y }

Computed Property → ES6


- Support for computed names in object property definitions.

//ES5
var obj = {
foo: "bar"
};
obj[ "baz" + quux() ] = 42;

//EC6
let obj = {
foo: "bar",
[ "baz" + quux() ]: 42
}

Method Properties → ES6


- Support for method notation in object property definitions, for both
regular functions and generator functions.
//EC6

78
obj = {
foo (a, b) {

},
bar (x, y) {

},
*quux (x, y) {

}
}

//ES5
obj = {
foo: function (a, b) {

},
bar: function (x, y) {

},
// quux: no equivalent in ES5

};

Destructuring Object → ES6


Object Matching → ES6
- Intuitive and flexible destructuring of Objects into individual variables
during assignment.

var { fName, lName } = person;

Object Matching, Deep Matching → ES6


var person = {
fullName: "Obada Kamal",
details: {

79
me: "there"
},
printAll(){
console.log('work like es6');
}
}
// ES5
var name = person.fullName;
var m = person.details.me;
var pr = person.printAll;

//ES6
var {fullName: name, details: {me: m}, printAll: pr} = person;

Object Matching, Default Values → ES6


- Simple and intuitive default values for destructuring of Objects and
Arrays.

var obj = { a: 1 }
var { a, b = 2 } = obj

Object Methods
- Methods are actions that can be performed on objects.
- Methods are stored in properties as function definitions.
- You access an object method as following:
objectName.methodName()
- If you access the method property without (), it will return
the function definition.

The this Keyword


- In a function definition, this refers to the "owner" of the function.

The in operator
- The in operator checks whether a property exists in the object.

80
'newProperty' in jane

Objects are Passed by Reference


- In JavaScript, object references are values. Because of this, objects
will behave like they are passed by reference.
- If a function changes an object property, it changes the original
value.
- Changes to object properties are visible (reflected) outside
the function.

• Avoid String, Number and Boolean as objects. They complicate your code
and slow down execution speed. Defined by a “new” keyword.

81
Display Objects
- Displaying a JavaScript object in HTML will output [object Object].
- Some common solutions to display JavaScript objects are:
1. Object Properties by name.

document.getElementById("demo").innerHTML =
person.name + "," + person.age + "," + person.city;

2. Object Properties in a Loop.

for (x in person) {
txt += person[x] + " ";
};

3. Object.values() → ES8

- Any JavaScript object can be converted to an array


using Object.values().

document.getElementById("demo").innerHTML = myArray;
var myArray = Object.values(person);

4. JSON.stringify()

- Any JavaScript object can be stringified (converted to a string)


with the JavaScript function JSON.stringify().

var myString = JSON.stringify(person);


document.getElementById("demo").innerHTML = myString;

- It will not stringify functions. So we can use toString() on


functions then JSON.stringify().
- It is also possible to stringify JavaScript arrays.

- NOTE: You can’t display getters and setters functions by these


ways.

82
Object and Internal Methods
- Almost everything JS programs do with objects is done using
properties, prototypes and functions. So when the ECMAScript
standard committee defined a set of 14 internal methods, the
common interface for all objects, it should come as no surprise that
they ended up focusing on these 3 fundamental things.
- The weird double brackets, [[ ]], emphasize that these
are internal methods, hidden from ordinary JS code. You can’t call,
delete or overwrite these like ordinary methods.

1. obj.[[Get]](key, receiver)

- Get the value of a property. called when JS code


does: obj.prop or obj[key].
- obj is the object currently being searched; receiver is the object
where we first started searching for this property. Sometimes we
have to search several objects. obj might be an object on receiver’s
prototype chain.

2. obj.[[Set]](key, value, receiver)

- Assign to a property of an object. called when JS code does: obj.prop


= value or obj[key] = value.
- In an assignment like obj.prop += 2, the [[Get]] method is called
first, and the [[Set]] method afterwards. Same goes for ++ and --.

3. obj.[[HasProperty]](key)

- Test whether a property exists. called when JS code


does: key in obj.

4. obj.[[Enumerate]]()

- List obj’s enumerable properties. called when JS code does: for (key
in obj) ...
- This returns an iterator object and that’s how a for–in loop gets an
object’s property names.

5. obj.[[GetPrototypeOf]]()

- Return obj’s prototype. called when JS code


does: obj.__proto__ or Object.getPrototypeOf(obj).

6. functionObj.[[Call]](thisValue, arguments)

- Call a function. called when JS code


does: functionObj() or x.method().
- Optional. Not every object is a function.

83
7. constructorObj.[[Construct]](arguments, newTarget)

- Invoke a constructor. called when JS code does: new Date(2890, 6,


2), for example.
- Optional. Not every object is a constructor.
- The newTarget argument plays a role in subclassing.

• The full list can be found in tables 5 and 6 of the ES6 standard.

84
Object Constructors
function Person(first, last, age, eye) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eye;
this.name = function() {return this.firstName + " " + this.lastName;};
}

- The way to create an "object type", is to use an object constructor


function (like above).
- Objects of the same type are created by calling the constructor
function with the new keyword.

var myFather = new Person("John", "Doe", 50, "blue");

- Constructor name should be start with Capital letter.

The this Keyword


- In a constructor function this does not have a value. It is a
substitute (‫ )استبدال‬for the new object. The value of this will become
the new object when a new object is created.

Adding a Property to a Constructor


- You can’t add a new property/function to an object constructor, you
must add it to the constructor function or by prototype “explained
below”.

85
Object Prototypes
Prototype-based programming
- It is a style of object-oriented programming where classes are not
explicitly defined, but rather derived by adding properties and
methods to an instance of another class or less frequently, adding
them to an empty object.
- In simple words: this type of style allows the creation of
an object without first defining its class.
- All JavaScript objects inherit properties and methods from a
prototype.
- When it comes to inheritance, JavaScript only has one construct:
objects. Each object has a private property which holds a link to
another object called its prototype. That prototype object has a
prototype of its own and so on until an object is reached
with null as its prototype. By definition, null has no prototype and
acts as the final link in this prototype chain.
- Nearly all objects in JavaScript are instances of Object which sits
on the top of a prototype chain.
- A prototype is a blueprint of an object. Prototype allows us to
use properties and methods on an object even if the properties
and methods do not exist on the current object.
- Whenever the property or method is not found on the current
object, the JavaScript engine will always try to look in its
prototype and if it still does not exist, it looks inside the
prototype's prototype and so on to the end when prototype being
NULL.
- Note: We want to reiterate that the methods and properties
are not copied from one object to another in the prototype
chain. They are accessed by walking up the chain as described
above.
- Note: The prototype chain is traversed only while retrieving
properties. If properties are set or deleted directly on the object,
the prototype chain is not traversed.
- So Object.prototype.toString(), Object.prototype.valueOf(),
etc., are available to any object types that inherit
from Object.prototype, including new object instances created
from the Person() constructor.
- Object.is(), Object.keys() and other members not defined inside
the prototype bucket are not inherited by object instances or
object types that inherit from Object.prototype. They are

86
methods/properties available just on the Object() constructor
itself.

Three different kinds of prototypal Object-Oriented.


1. Concatenative inheritance: The process of inheriting features
directly from one object to another by copying the source objects
properties without retaining a reference between the two objects.
In JavaScript, source prototypes are commonly referred to
as mixins/Cloning.
- Cloning is a great way to store default state for objects. Since ES6,
this feature has a convenience utility in JavaScript
called `Object.assign()`. Prior to ES6, this was commonly done
with Underscore/Lodash’s `.extend()` jQuery’s `$.extend()`.
const proto = {
hello: function hello() { // IN ES6: hello()
return `Hello, my name is ${ this.name }`;
}
};

const george = Object.assign({}, proto, {name: 'George'});


const msg = george.hello();
console.log(msg); // Hello, my name is George

2. Prototype delegation: In JavaScript, an object may have a link


to a prototype for delegation. If a property is not found on the
object, the lookup is delegated to the delegate
prototype, which may have a link to its own delegate prototype,
and so on up the chain until you arrive at `Object.prototype`,
which is the root delegate. This is the prototype that gets hooked
up when you attach to a `Constructor.prototype` and instantiate
with new. You can also use `Object.create()` for this purpose and
even mix this technique with concatenation in order to flatten
multiple prototypes to a single delegate or extend the object
instance after creation.
- You can avoid property delegation by setting the prototype
to `null` using `Object.create(null)`.
- One major drawback to delegation is that it’s not very good for
storing state. If you try to store state as objects or arrays,
mutating any member of the object or array will mutate the
member for every instance that shares the prototype. In order to

87
preserve instance safety, you need to make a copy of the state for
each object.

function Greeter (name) {


this.name = name || 'John Doe';
}

Greeter.prototype.hello = function hello () {


return 'Hello, my name is ' + this.name;
}

var george = new Greeter('George');


var msg = george.hello();
console.log(msg); // Hello, my name is George

3. Functional inheritance: In JavaScript, any function can create


an object. When that function is not a constructor or class, it’s
called a factory function. Functional inheritance works by
producing an object from a factory and extending the produced
object by assigning properties to it directly (using concatenative
inheritance). Functional inheritance has been in common use in
JavaScript for a long time.
- The primary advantage of using functions for extension is that it
allows you to use the function closure to encapsulate private
data. In other words, you can enforce private state.
import Events from 'eventemitter3';

const rawMixin = function () {


const attrs = {};

88
return Object.assign(this, {
set (name, value) {
attrs[name] = value;

this.emit('change', {
prop: name,
value: value
});
},

get (name) {
return attrs[name];
}
}, Events.prototype);
};

const mixinModel = (target) => rawMixin.call(target);


const george = { name: 'george' };
const model = mixinModel(george);

model.on('change', data => console.log(data));


model.set('name', 'Sam');
/*
{
prop: 'name',
value: 'Sam'
}*

- Prototype & Inheritance MDN

89
Object Methods
ES5 Object Methods
1. Object.defineProperty(object, property, {value : value})
o Adding or changing an object property.
// Define a getter
Object.defineProperty(person, "fullName", {
get : function () {return this.firstName + " " + this.lastName;}
});

2. Object.defineProperties(object, descriptors)
o Adding or changing many object properties.
Object.defineProperties(person, {
fullName: {
get: function(){
return this.firstName + " " + this.lastName;
},
enumerable: true,
configurable: true
},
"language":{
value: "AR",
enumerable: true,
writable: true,
configurable: true
}
})

3. Object.getOwnPropertyDescriptor(object, property)
o Returns Properties and show Meta data and value.

4. Object.getOwnPropertyNames(object)
o Returns all properties (enumerable or not) as an array
but not one added to prototype.

90
5. Object.keys(object)
o Returns enumerable properties as an array.

6. Object.getPrototypeOf(object)
o Returns the prototype.

7. Object.preventExtensions(object)
o Prevents new properties from ever being added to an
object, may properties still be deleted. You can still
change the values.

8. Object.isExtensible(object)
o Returns true if properties can be added to an object .

9. Object.seal(object)
o Preventing new properties from being added to it and
marking all existing properties as non-configurable.
Values of present properties can still be changed as
long as they are writable.

10. Object.isSealed(object)
o Returns true if object is sealed.

11. Object.freeze(object)
o A frozen object can no longer be changed; freezing an
object prevents new properties from being added to it,
existing properties from being removed, prevents
changing the enumerability, configurability or
writability of existing properties and prevents the
values of existing properties from being changed. In
addition, freezing an object also prevents its prototype
from being changed.

12. Object.isFrozen(object)
o Returns true if object is frozen.

ES6 Object Methods


1. Object.assign(target, ...sources)

91
o Copies all enumerable own properties from one or
more source objects to a target object. It returns target object
after changed.

let newTarget = Object.assign(target, src1, src2 ...)

o Properties in the target object are overwritten by properties in


the sources if they have the same key in the parameters order.
o Both String and Symbol properties are copied.
o NOTE: It will copy reference for properties which are objects,
so any change on object will change the copied properties.

2. Object.is(val1, val2)
o determines whether two values are the same value. Two values
are the same if one of the following holds:
▪ both undefined
▪ both null
▪ both true or both false
▪ both strings of the same length with the same characters
in the same order
▪ both the same object (means both object have same
reference)
▪ both numbers and
• both +0
• both -0
• both NaN
• or both non-zero and both not NaN and both have
the same value.

3. Object.setPrototypeOf(obj, prototype)
o It’s very slow, avoid using it.

ES8 Object Methods


1. Object.entries(object)
o Method returns an array of [key, value] pairs for object
properties.

2. Object.values(object)
o Method returns values for object properties.

92
3. Object.getOwnPropertyDescriptors(object)
o Returns all Properties and show Meta data and values.

Rest/Spread Operator for Objects → ES9


Rest properties
const { first, second, ...others } = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5 }

first // 1
second // 2
others // { third: 3, fourth: 4, fifth: 5 }

Spread properties
o Allow to create a new object by combining the properties of the
object passed after the spread operator
const items = { first, second, ...others }
items //{ first: 1, second: 2, third: 3, fourth: 4, fifth: 5 }

Object.fromEntries(iterable) → ES10
- Transforms a list of [key, value] pairs into an object.
- An iterable such as Array or Map or other objects implementing
the iterable protocol. Return a new object.

93
this Keyword
- The JavaScript this keyword refers to the object it belongs to.
- It has different values depending on where it is used:
1. this alone, refers to the global object.
2. this in an event, refers to the element that received the event.
3. Methods like call(), apply() and bind() can refer this to any
object.

const call = {
caller: "mom",
says: function() {
console.log(`Hey, ${this.caller} just called.`);
}
};

call.says();

- Here we have a function declaration inside the call object. As a


general rule, this is determined by the object invoking a
function. Therefore, when the call object invokes says function
(call.says()), the this keyword inside the says function refers to
the call object, making this.caller equal to "mom".

const call = {
caller: "mom",
says: () => {
console.log(`Hey, ${this.caller} just called.`);
}
};

call.says();

- Arrow functions, as part of ES6 syntax, do NOT have their


own this keyword. Instead, they will use the this keyword of
whatever this was outside the function when it was created.
- In other words, this inside the arrow function is not bound to our
call object, but instead is already bound to where the call object is
being created originally, which in this case is the global
object. because the global object does not have a caller property,
this.caller is undefined.

94
const call = {
caller: "mom",
says: function() {
console.log(`Hey, ${this.caller} just called.`);
}
};
let newCall = call.says;
newCall();

- Here, we assign a new variable to the says function inside the call
object And then we invoke the variable, which is a simple function
call.
- Notice where we invoke the function. Is it inside the call object?
No. We are invoking newCall() function globally, which in turn
makes the this keyword equal to the global object.
- since the global object does not have a caller property, you get
"undefined" as a result.
- By now, you might notice a key pattern:
Regular functions change their behaviors BASED ON the
object that is CALLING the function.

var box = {
color: 'green',
position: 1,
clickMe: function() {
document.querySelector('body').addEventListener('click', () => {
var str = 'This is box number ' + this.position + ' and it is ' + this.color;
alert(str);
});
}
}

- The amazing thing about arrow functions is that they share the
lexical this keyword of their surroundings. So, in our example
here it shares the this keyword with its outer function.
This this keyword for the outer function refers to the box object,
so this.position and this.color will have the correct values
of green and 1.

95
Function Type Strict Mode In Object this Reference to

Regular No No Global Object

Regular Yes No undefined

Regular No/Yes Yes Owner Object

Arrow No/Yes No/Yes Global Object


avoid using it as method

Standardized globalThis object → ES10


- The global this was not standardized before ES10.
In production code you would “standardize” it across multiple
platforms on your own by writing this monstrosity.

// The global this was not standardized before ES1O. The solution was
var getGlobal = function ( ) {
if (typeof self !== 'undefined') { return self; }
if (typeof window !=='undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error( 'unable to locate global object' );
}

// ES10 added globalThis object which sould be used from now on to access global scope
on any platform

// Access global array constructor


globalThis.Array(0, 1, 2); //[0, 1, 2]

// Similar to window.v = { value: true } in <= ESIO in Browser


globalThis.v = { value:true };

- This keyword explanation.

96
Arrays
- Array is a special variable which can hold more than one value at
a time (store multiple values in a single variable).
- In general, arrays in JavaScript are sparse – they can have holes
in them, because an array is simply a map from indices to values.
- Dense arrays, don’t have holes in them, JavaScript don’t use this
type.

Creating an Array
1. Using an array literal, A declaration can be multiple lines.

var array_name = ["item1", "item2", ...];

2. Using the JavaScript keyword new.

var array_name = new Array("item1", "item2", ...);

- For simplicity, readability and execution speed, use the first one.

Access the Elements of an Array


- You access an array element by referring to the index number.
- Array indexes start with 0.

Changing an Array Element


arrayVar[index] = value;

Access the Full Array


- With JavaScript, the full array can be accessed by referring to the
array name.

var x = arrayVar;

Arrays are Objects


- Arrays are a special type of objects. The typeof operator in
JavaScript returns "object" for arrays.
- Arrays use numbers to access its "elements", but Objects
use names to access its "members".

97
Array Elements Can Be Objects
- you can have variables of different types in the same Array. You
can have objects in an Array. You can have functions in an Array.
You can have arrays in an Array.

Array Properties
- The length property of an array returns the length of an array
(the number of array elements).
- It is always one more than the highest array index.
- It provides an easy way to append a new element to the end of an
array.

array[array.length] = newValue;

Accessing the Last Array Element


var last = array[array.length - 1];

Destructring Array → ES6


Array Matching → ES6
- Intuitive and flexible destructuring of Arrays into individual variables
during assignment.

var list = [ 1, 2, 3 ]
var [ a, , b ] = list

Array Matching, Default Values → ES6


- Simple and intuitive default values for destructuring of Objects and
Arrays.
var list = [ 1 ]
var [ x, y = 2 ] = list

Rest/Spread Operator for arrays → ES6


- Spreading of elements of an iterable collection (like an array or a
string) into both literal elements and individual function parameters.

Spreading array elements → ES6

98
var params = [ "hello", true, 7 ]
var other = [ 1, 2, ...params ]//[ 1, 2, "hello", true, 7 ]

Spreading array elements in function parameters → ES6


const numbers = [1, 2, 3, 4, 5]
const sum = (a, b, c, d, e) => a + b + c + d + e
const sumOfNumbers = sum(...numbers)

Associative Arrays
- Arrays with named indexes are called associative arrays (or
hashes).
- JavaScript does not support arrays with named indexes, so
always use numbered indexes.

WARNING !!
If you use named indexes, JavaScript will redefine the array to a standard
object. After that, some array methods and properties will
produce incorrect results.

The Difference Between Arrays and Objects in JavaScript


- arrays use numbered indexes., so use it when you want the
element names to be numbers.
- objects use named indexes, so use it when you want the
element names to be strings (text).

How to Recognize an Array


- the JavaScript operator typeof returns "object".

1. isArray(arryVariable)→ ES5
- determines whether an object is an array. Return true or false.
- not supported in older browsers.

Array.isArray(fruits);

2. To solve this problem you can create your own isArray() function.

function isArray(x) {

99
return x.constructor.toString().indexOf("Array") > -1;
}

- It returns true if the object prototype contains the word "Array".


- Or even simpler, you can check if the object is an Array function.

function isArray(myArray) {
return myArray.constructor === Array;
}

3. The instanceof operator returns true if an object is created by a given


constructor.

arrayVar instanceof Array; // returns true

Declares a Three Dimensional Array


var myArray = [[[]]];

100
Array Methods
Converting Arrays to Strings
1. The JavaScript method toString() converts an array to a string of
(comma separated) array values.
2. The join(separator) method also joins all array elements into a
string without any separator, but in addition you can specify the
separator.

Automatic toString()
- JavaScript automatically converts an array to a comma separated
string when a primitive value is expected.
- This is always the case when you try to output an array.

document.getElementById("out").innerHTML = arrayVar;

Popping and Pushing


- Popping items out of an array or pushing items into an array.

1. Popping
- The pop() method removes the last element from an array, it
returns the value popped out “deleted”.

arrayVar.pop();

2. Pushing
- The push(val1, val2 ...) method adds a new element to an
array at the end, it returns the new array length.

arrayVar.push(newValue);

Shifting Elements
- The shift() method removes the first array element and "shifts"
all other elements to a lower index, it returns the string that was
shifted out “deleted”.

var fruits = ["Banana", "Orange", "Apple", "Mango"];


var x = fruits.shift(); // the value of x is "Banana"

Unshifting Elements

101
- the unshift(newValue) method adds a new element to an array at
the beginning and "unshifts" older elements, it returns the new
array length.
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.unshift("Lemon"); // Returns 5

Deleting Elements (Don’t use it)


- elements can be deleted by using the JavaScript operator delete.

delete arrayVar[index];

- Using delete may leave undefined holes in the array. Use pop() or
shift() instead.

Splicing an Array
- The splice(start, deleteCount, ele1, ele2 ...) method can be
used to add new items to an array, it returns an array with deleted
items if there is.
- With clever parameter setting, you can use it to remove elements
without leaving "holes" in the array.

fruits.splice(0, 1); // Removes the first element of fruits

- start
o If it’s > array.length, it will be set to the length of the array (at the
end).
o If it is negative, it will start from array.length – start.
o If array.length + start < 0, it will begin from index 0.
- deleteCount
o It’s Optional. If it is omitted or if its value >= array.length - start ,
then delete all elements from start to the end of the array.
o If it is 0 or negative, no elements are removed.
- The ele1, ele2 ... to add to the array, beginning from start. It’s
Optional.
- Returned value is an array containing the deleted elements or empty array if
no deleted elements.

Merging (Concatenating) Arrays


- The concat(arr1, arr2 ...) method return a new array by
merging (concatenating) existing arrays.

102
var newArray = array1.concat(array2, array3 ...);

- It can also takes values as arguments.

var newArray = arr1.concat([value1, value2]);

- If we merge arrays of objects, it will have the reference of objects, so


any change on the objects in the new array will affect the original
one.

Slicing an Array
- The slice(start, end) method slices out a piece of an array into a
new array.

newArray = arrayVar.slice(2);

- start
o It is Optional. If it is undefined, it begins from index 0.
o It can be a negative index, indicating an offset from the end.
o If it is greater than the index range, an empty array is
returned.
- end
o It is Optional and extracts up to but not including.
o It can be a negative index, indicating an offset from the end.
o If it is omitted or greater than the array length, it will slice out
the rest of the array from start.

Reversing an Array
- The reverse() method reverses the elements in an array, it’s change
the same array.
- If you want array reversed alphabetically, first sort the array then
reverse it, but anyway it will reverse the array.

Sorting an Array
- The sort(compareFunction) method sorts an array alphabetically,
it’s change the same array.
- The default sort order is ascending. It’s converting the elements
into strings then comparing their sequences of UTF-16 code units
values.

arrayVar.sort();

103
- compareFunction is an optional argument which is a function that
compares two elements of the array.

Numeric Sort
- By default, the sort() function sorts values as strings.
- if numbers are sorted as strings, "25" > "100",
because "2" > "1".
- You can fix this by providing a compare function.

The Compare Function


- define an alternative sort order.
- The compare function should return a negative, zero or positive
value, depending on the arguments.

arrayVar.sort(function(a, b){return a - b});

- When the sort() function compares two values, it sends the values
to the compare function, and sorts the values according to the
returned value.
- If the result is negative a is sorted before b.
- If the result is positive b is sorted before a.
- If the result is 0, no changes are done with the sort order of the two
values.
- This sort is ascending.
- Descending sort is done by changing compare function to be:

arrayVar.sort(function(a, b){return b - a});

Sorting an Array in Random Order


arrayVar.sort(function(a, b){return 0.5 - Math.random()});

Find the Highest (or Lowest) Array Value


- After you have sorted an array, you can use the index to obtain the
highest and lowest values.
- Sorting a whole array is a very inefficient method if you only want to
find the highest (or lowest) value.

104
1. Array.reduce() can be used to find the maximum (minimum)
element in a numeric array, by comparing each value. (Reduce
Explained Later)
var arrayVar = [1,2,3];
var max = arr.reduce(function(a, b) {
return Math.max(a, b); // Math.min(a, b)
});

2. You can use Math.max.apply to find the highest number in an array.


It’s apply to Math.min.apply too.

var max = Math.max.apply(null, arrayVar);

3. The new spread operator is a shorter way of writing


the apply solution to get the maximum of an array.

var max = Math.max(...arr);


var min = Math.min(...arr);

However, both spread (...) and apply will either fail or return the
wrong result if the array has too many elements, because they try to
pass the array elements as function parameters. The reduce solution
does not have this problem.

Home built Methods for Min and Max


function myArrayMax(arr) {
var len = arr.length;
var max = -Infinity; // var min = Infinity
while (len--) {
if (arr[len] > max) { // arr[len] < min
max = arr[len];
}
}
return max;
}

Sorting Object Arrays


- Even if objects have properties of different data types,
the sort() method can be used to sort the array.

105
- The solution is to write a compare function to compare the property
values.

var cars = [
{type:"Volvo", year:2016},
{type:"Saab", year:2001},
{type:"BMW", year:2010}
];
cars.sort(function(a, b){return a.year - b.year});

106
Array Iteration Methods
- Array iteration methods operate on every array item.

ArrayVar.forEach() → ES5
- The forEach(callbackFunction) method calls a function once for
each array element and changing the same array.
- Each callback function receive 3 parameters: value, index and the
array itself. index and array can be omitted if not used.

arrayVar. forEach(myFunction);
function myFunction(value, index, array)
{ //any code here }

- It doesn’t execute the function for array elements without values.

ArrayVar.map() →ES5
- The map(callbackFunction) method creates a new array by
performing a function on each array element, does not change the
original array.
- It doesn’t execute the function for elements without values, but
returned array will have the hole elements.
- Each callback function receive 3 parameters: value, index and the
array itself. index and array can be omitted if not used.

var newArray = arrayVar.map(myFunction);

- You shouldn't be using it if:


1. you're not using the array it returns.
2. you're not returning a value from the callback.

ArrayVar.filter() → ES5
- The filter(callbackFunction) method creates a new array with
array elements that passes a test. So returned value should be true
or false.

var newArray = arrayVar.filter(myFunction);

- Each callback function receive 3 parameters: value, index and the


array itself. index and array can be omitted if not used.

107
ArrayVar.reduce() & ArrayVar.reduceRight() → ES5
- The reduce(callbackFunction, initialValue) method runs a
function on each array element to produce (reduce it to) a single
value, it works from L → R in the array.
- The reduceRight(callbackFunction, initialValue) same method,
but it works from R → L in the array.
- Both does not reduce the original array.
- initialValue is optional.
- It doesn’t execute the function for elements without values.
var sum = numbers1.reduce(myFunction);
function myFunction(total, value, index, array) {
return total + value;
}

- Each callback function receive 4 parameters: (the initial value OR


previously returned value), value, index and the array itself. index
and array can be omitted if not used.

ArrayVar.every() → ES5
- The every(callbackFunction) method check if all array values pass a
test and returns a single value. It stop when the test return false.
- If ALL members in the array pass the test it return true else it return
false.

var newArray = arrayVar.every(myFunction);

- Each callback function receive 3 parameters: value, index and the


array itself. index and array can be omitted if not used.
- It doesn’t execute the function for elements without values.

ArrayVar.some() → ES5
- The some(callbackFunction) method tests whether at least
one element in the array passes the test return true else it return
false. It returns a single value.

var newArray = arrayVar.some(myFunction);

- Each callback function receive 3 parameters: value , index and the


array itself. index and array can be omitted if not used.

108
- It doesn’t execute the function for elements without values.

ArrayVar.indexOf() → ES5
- the indexOf(searchFor, startIndex) method searches an array for
an element value and returns its position.

var positionIndex = arrayVar.indexOf(value);

- startIndex is optional. Negative values will start at the given position


counting from the end and search to the end.
- returns -1 if the item is not found.
- If the item is present more than once, it returns the position of the
first occurrence.

ArrayVar.lastIndexOf() → ES5
- Array.lastIndexOf(searchFor, startIndex) is the same
as Array.indexOf(), but returns the position of the last
occurrence of the specified element.

var a = arrayVar.lastIndexOf(value);

- startIndex is Optional. Negative values will start at the given


position counting from the end, and search to the beginning.
- BOTH are using strict equality (===).

All methods above Not supported in IE 8 and earlier.

ArrayVar.entries () → ES6
- The entries() method returns an Array Iterator object with
key/value pairs.

const arrayVar = ['a', 'b', 'c'];


const iterator1 = arrayVar.entries();
console.log(iterator1.next().value); // [0, "a"]

ArrayVar.find() → ES6

109
- The find(callbackFunction) method returns the value of the first
array element that passes a test function. Otherwise, undefined is
returned.
var firstValue = arrayVar.find(myFunction);

- Each callback function receive 3 parameters: value , index and the


array itself. index and array can be omitted if not used.
- It is execute the function for elements without values.
- Supported in some browsers.

ArrayVar.findIndex() → ES6
- The findIndex(callbackFunction) method returns the index of the
first array element that passes a test function. Otherwise, -1 is
returned.
- Each callback function receive 3 parameters: value , index and the
array itself. index and array can be omitted if not used.
- It is execute the function for elements without values.
- Supported in some browsers.

Array.from() → ES6
- The Array.from(object, mapFunction, thisValue) static method
creates a new, shallow-copied Array instance from an array-like,
iterable object or any object with a length property.
- let you create Arrays from:
1. array-like objects (objects with a length property and indexed
elements); or
2. iterable objects (objects such as Map and Set).
- mapFunction, thisValue are Optional.

- mapFunction allows you to execute a map() function on each element of the


array being created.
function myMap(value, index){
return index;
}
var newArray = Array.from({length: 5}, myMap);

Array.of() → ES6
- Array.of(el1, el2 ...) method creates a new Array instance from
a variable number of arguments, regardless of number or type of the
arguments.

110
- The difference between Array.of() and the Array constructor is in
the handling of integer arguments: Array.of(7) creates an array
with a single element, 7, whereas Array(7) creates an empty array
with a length property of 7.

Array.of(1); // [1]
Array.of(1, 2, 3); // [1, 2, 3]
Array.of(undefined); // [undefined]

Array.fill() → ES6
- Array.fill(value, start, end) method fills the specified elements
in an array with a static value.
- You can specify the position of where to start and end the filling. If
not specified, all elements will be filled.
- It overwrites the original array.
- Value Required. The value to fill the array with.
- start Optional. The index to start filling the array (default is 0).
- end Optional. The index to stop filling the array (default
is array.length).

ArrayVar.includes() → ES7
- The includes(searchFor, start) method determines whether an
array contains a specified element.
- This method returns true if the array contains the element,
and false if not.
- It is case sensitive.
- it can be applied to other kinds of objects (e.g. array-like objects)
- start
o is optional.
o If it is >= length of the array, false is returned. The array will
not be searched.
o If the computed index (start + arr.length) is <= -1, the
entire array will be searched.

ArrayVar.flat() → ES10
- link

111
ArrayVar.flatMap() → ES10
- link

Complete Array Reference

112
Date Objects
- Date objects are static. The computer time is ticking, but date
objects are not.

JavaScript Date Output


- By default, JavaScript will use the browser's time zone and display a
date as a full text string.

Creating Date Objects


- Date objects are created with the new Date() constructor.
- There are 4 ways to create a new date object.

1. new Date()
- new Date() creates a new date object with the current date and
time.

var d = new Date();

2. new Date(year, month, ...)


- new Date(year, month, day, hours, minutes, seconds,
milliseconds) creates a new date object with a specified date and
time.

var d = new Date(2018, 11, 24, 10, 33, 30, 0);

- Note: JavaScript counts months from 0 to 11. January is 0.


December is 11.
- You can just provide year and month but omitting month will handle
it as milliseconds.
- Previous Century
One and two digit years will be interpreted as 19xx.

3. new Date(dateString)
- new Date(dateString) creates a new date object from a date
string.

var d = new Date("October 13, 2014 11:13:00");

113
4. new Date(milliseconds)
- new Date(milliseconds) creates a new date object as zero time
(1.1.1970) plus milliseconds.

var d = new Date(-100000000000); // October 31 1966

Date Methods
- methods operate on a Date object.
- Displaying Dates:
o JavaScript will output the default dates format, when you
display a date object in HTML, it is automatically converted to a
string.
o The toUTCString() method converts a date to a UTC string (a
date display standard).
UTC : UTC (Universal Time Coordinated) is the same as GMT
(Greenwich Mean Time).

new Date().toUTCString(); // Thu, 26 Mar 2020 19:55:40 GMT

o The toDateString() method converts a date to a more


readable format.

new Date().toDateString(); // Thu Mar 26 2020

114
Date Formats
JavaScript Date Input
- There are generally 3 types of JavaScript date input formats:

Type Example

ISO Date "2015-03-25" (The International Standard)

Short Date "03/25/2015"

Long Date "Mar 25 2015" or "25 Mar 2015"

1. JavaScript ISO Dates


- ISO 8601 is the international standard for the representation of
dates and times and preferred by JavaScript. It’s syntax
(YYYY-MM-DD).
- It can be written without specifying the day (YYYY-MM).
- It can be written without month and day (YYYY).
- It can be written with added hours, minutes and seconds (YYYY-
MM-DDTHH:MM:SSZ).
var d = new Date("2015-03-25T12:00:00Z");

o Date and time is separated with a capital T.


o UTC time is defined with a capital letter Z.
o If you want to modify the time relative to UTC, remove the
Z and add +HH:MM or -HH:MM instead.

2. JavaScript Short Dates.


- Short dates are written with an "MM/DD/YYYY” syntax.
- months or days with no leading zeroes may produce an error.
- The behavior of "YYYY/MM/DD" is undefined.
- The behavior of "DD-MM-YYYY" is also undefined.

3. JavaScript Long Dates.


- Long dates are most often written with a "MMM DD YYYY” syntax like
this.
- Month and day can be in any order. “MMM DD” or “DD MMM”.
- Month can be written in full (January), or abbreviated (Jan).

115
- Commas are ignored. Names are case insensitive.

var d = new Date("JANUARY, 25, 2015");

JavaScript Date Output


- Independent of input format, JavaScript will output dates in full text
string format.

Time Zones
- When setting a date, without specifying the time zone, JavaScript will
use the browser's time zone.

Date Input - Parsing Dates


- If you have a valid date string, you can use the Date.parse() method
to convert it to milliseconds.
- Then use the number of milliseconds to convert it to a date object

116
Get Date Methods
The now() Method → ES5
- Date.now() returns the number of milliseconds since zero date
(January 1. 1970 00:00:00 UTC), returns the same as getTime()
performed on a Date object.

The getTime() Method


- The getTime() method returns the number of milliseconds since
January 1, 1970.

var d = new Date();


document.getElementById("demo").innerHTML = d. getTime();

The getFullYear() Method


- The getFullYear() method returns the year of a date as a four digit
number.

d.getFullYear();

The getMonth() Method


- The getMonth() method returns the month of a date as a number (0-
11).

d.getMonth();

- You can use an array of names and return the month as a name.

The getDate() Method


- The getDate() method returns the day of a date as a number (1-31).

d.getDate();

The getHours() Method


- The getHours() method returns the hours of a date as a number (0-
23).
d.getHours();

The getMinutes() Method

117
- The getMinutes() method returns the minutes of a date as a number
(0-59).

d.getMinutes();

The getSeconds() Method


- The getSeconds() method returns the seconds of a date as a number
(0-59).

d.getSeconds();

The getMilliseconds() Method


- The getMilliseconds() method returns the milliseconds of a date as
a number (0-999).

d.getMilliseconds();

The getDay() Method


- The getDay() method returns the weekday of a date as a number (0-
6).

d.getDay();

- You can use an array of names and return the weekday as a name.
- In JavaScript, the first day of the week (0) means "Sunday".

UTC Date Methods

Method Description

getUTCDate() Same as getDate(), but returns the UTC date

getUTCDay() Same as getDay(), but returns the UTC day

getUTCFullYear() Same as getFullYear(), but returns the UTC year

getUTCHours() Same as getHours(), but returns the UTC hour

getUTCMilliseconds() Same as getMilliseconds(), but returns the UTC


milliseconds

getUTCMinutes() Same as getMinutes(), but returns the UTC minutes

getUTCMonth() Same as getMonth(), but returns the UTC month

getUTCSeconds() Same as getSeconds(), but returns the UTC seconds

118
Complete Date Reference.

119
Set Date Methods
- Set Date methods let you set date values (years, months, days,
hours, minutes, seconds, milliseconds) for a Date Object.

The setFullYear() Method


- The setFullYear(years, months, days) method sets the year of a
date object. In this example to 2020.

var d = new Date();


d.setFullYear(2020, 11, 3);

- months, days are optional parameters.


- Return milliseconds from 1.1.1970 to that date we set.

The setMonth() Method


- The setMonth(months, days) method sets the month of a date object
(0-11).

d.setMonth(11);

- days is optional parameter.


- If months was -1, represent December of the previous year and 12
represents January of the following year
- Return milliseconds from 1.1.1970 to that date we set.

The setDate() Method


- The setDate(days) method sets the day of a date object (1-31).

d.setDate(15);

- If days is negative, the date will be set counting backwards from the
last day of the previous month.
- If days was 0, the date will be set to the last day of the previous
month.
- Return milliseconds from 1.1.1970 to that date we set.

The setHours() Method


- The setHours(hours, minutes, second, ms) method sets the hours
of a date object (0-23).

d.setHours(22);

120
- Return milliseconds from 1.1.1970 to that date we set.
- minutes, second, ms are optional parameters.

The setMinutes() Method


- The setMinutes(minutes, seconds, ms) method sets the minutes of
a date object (0-59).

d.setMinutes(30);

- Return milliseconds from 1.1.1970 to that date we set.


- second, ms are optional parameters.

The setSeconds() Method


- The setSeconds(seconds, ms) method sets the seconds of a date
object (0-59).

d.setSeconds(30);

- Return milliseconds from 1.1.1970 to that date we set.


- ms is optional parameter.

The setMilliseconds() Method


- The setMilliseconds(ms) method sets the milliseconds of a date
object (0-999).

d.setMilliseconds(30);

- Return milliseconds from 1.1.1970 to that date we set.

Compare Dates
- It can be compared easily by using them and bitwise operators.

date1 > date2

If you added more than limit in any function above, it will the change the
whole date accordingly.

121
Map Data-Structure → ES6
- Map is object holds key-value pairs and remembers the original
insertion order of the keys. Any value (both objects and primitive
values) may be used as either a key or a value.
- Maps are more useful over objects when you just need a simple look
up structure for data storing.

Map Creation
const m = new Map()

Initialize a map with values


- You can initialize a map with a set of values.

const m = new Map([['color', 'red'], ['owner', 'Flavio'], ['age', 2]])

Add items to a Map


- You can add items to the map by using the set() method.
- Return the new map after addition.
m.set('color', 'red')
m.set('age', 2)

Get an item from a map by key


- You can get items out of a map by using get().

const color = m.get('color')


const age = m.get('age')

Map keys
- any value can be used as the key, even objects.
- If you try to get a non-existing key using get() out of a map, it will
return undefined.

const m = new Map()


m.set(NaN, 'test')
m.get(NaN) //test
const m = new Map()
m.set(+0, 'test')

122
m.get(-0) //test

Delete an item from a map by key


- Use the delete() method. Return true/false to indicate the success
of deletion.

m.delete('color')

Delete all items from a map


- Use the clear() method.

m.clear()

Check if a map contains an item by key


- Use the has() method. Return true/false.

const hasColor = m.has('color')

Find the number of items in a map


- Use the size property.

const size = m.size

Iterating over a map


Iterate over map keys
- Map offers the keys() method we can use to iterate on all the keys.

for (const k of m.keys()) {


console.log(k)
}

Iterate over map values


- The Map object offers the values() method we can use to iterate on
all the values.

for (const v of m.values()) {


console.log(v)
}

123
Iterate over map key, value pairs
- The Map object offers the entries() method we can use to iterate on
all the values.

for (const [k, v] of m.entries()) {


console.log(k, v)
}

- which can be simplified to

for (const [k, v] of m) {


console.log(k, v)
}

Convert to array
Convert the map keys into an array
const a = [...m.keys()]

Convert the map values into an array


const a = [...m.values()]

WeakMap
- A WeakMap is a special kind of map.
- In a map object, items are never garbage collected. A WeakMap
instead, let’s all its items be freely garbage collected. Every key
of a WeakMap is an object. When the reference to this object is lost,
the value can be garbage collected.
- Here are the main differences:
o you cannot iterate over the keys or values (or key-values) of a
WeakMap.
o you can’t clear all items from a WeakMap.
o you can’t check its size.

124
Set Data-Structure → ES6
- Object lets you store unique values of any type, whether primitive
values or object references.
- Set objects are collections of values. You can iterate through the
elements of a set in insertion order. A value in the Set may only
occur once; it is unique in the Set's collection.

Initialize a Set
- A Set is initialized by calling the constructor.

const s = new Set()

Initialize a Set with values


- You can initialize a Set with a set of values.

const s = new Set([1, 2, 3, 4])

Add items to a Set


- You can add items to the Set by using the add method.

s.add('one')
s.add('two')

- A set only stores unique elements, so calling s.add('one') multiple


times won’t add new items.
- You can’t add multiple elements to a set at the same time. You
need to call add() multiple times.

Check if an item is in the set


- Once an element is in the set, we can check if the set contains it.
Return true or false as indication.
s.has('one') //true
s.has('three') //false

Delete an item from a Set by key


- Use the delete() method.

s.delete('one')

125
Determine the number of items in a Set
- Use the size property.

s.size

Delete all items from a Set


- Use the clear() method.

s.clear()

Iterate the items in a Set


- Use the keys() or values() methods - they are equivalent.

for (const k of s.keys()) {


console.log(k)
}

for (const k of s.values()) {


console.log(k)
}

- The entries() method returns an iterator, which you can use like
this.

const i = s.entries()
console.log(i.next())

- calling i.next() will return each element as a { value, done = false


} object until the iterator ends, at which point done is true.
- You can also use the forEach() method on the set.

s.forEach(v => console.log(v))

- or you can just use the set in a for..of loop.

for (const k of s) {
console.log(k)
}

Convert the Set keys into an array


const a = [...s.keys()]
// or

126
const a = [...s.values()]

Relation with Array objects


- Use the regular Set constructor to transform an Array into a Set.

let myArray = ['value1', 'value2', 'value3']

let mySet = new Set(myArray)

- Use the spread operator to transform a set into an Array.

console.log([...mySet]) // Will show you exactly the same Array as myArray

Remove duplicate elements from the array


- Use to remove duplicate elements from the array

const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]

console.log([...new Set(numbers)]) // [2, 3, 4, 5, 6, 7, 32]

A WeakSet
- A WeakSet is a special kind of Set.
- In a Set, items are never garbage collected. A WeakSet instead, let’s
all its items be freely garbage collected. Every key of a WeakSet is
an object. When the reference to this object is lost, the value can be
garbage collected.
- Here are the main differences:
o you can’t iterate over the WeakSet.
o you can’t clear all items from a WeakSet.
o you can’t check its size.

127
Reflect Object → ES6
- Unlike most global objects, Reflect is not a constructor. You can’t use
it with a new operator or invoke the Reflect object as a function. All
properties and methods of Reflect are static (just like
the Math object).
- The Reflect object provides static functions, some of these methods
are also the same as corresponding methods on Object, although
they do have some subtle (‫ )خفيف‬differences between them.

Static methods
1. Reflect.apply(targetFunc, thisArgument, argumentsList)
o Calls a target function with arguments as specified by
the argumentsList parameter.

Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111])


// "hello"

Reflect.apply(RegExp.prototype.exec, /ab/, ['confabulation']).index


// 4

2. Reflect.construct(object, argumentsList[, newTarget])


o Method acts like the new operator, but as a function. It is
equivalent to calling new target(...args). It gives also the
added option to specify a different prototype.

let d = Reflect.construct(Date, [1776, 6, 4])


d instanceof Date // true
d.getFullYear() // 1776

3. Reflect.defineProperty(object, property, {value})


o Similar to Object.defineProperty(). Returns a Boolean that
is true if the property was successfully defined, false
otherwise.

if (Reflect.defineProperty(object1, 'property1', { value: 42 })) {


console.log('property1 created!');
// expected output: "property1 created!"
} else {
console.log('problem creating property1');

128
}

4. Reflect.deleteProperty(object, property)
o The delete operator as a function. Equivalent to
calling delete object[property]. Returns a Boolean that
is true if the property was deleted successful, false otherwise.

Reflect.deleteProperty(obj, 'x') // true

5. Reflect.get(object, property[, receiver])


o Returns the value of the property. Works like getting a property
from an object (target[propertyKey]) as a function.

Reflect.get(obj, 'x') // 1

6. Reflect.set(object, property, value[, receiver])


o A function that assigns values to properties. Returns
a Boolean that is true if the update was successful, false
otherwise.
Reflect.set(object1, 'property1', 42);

7. Reflect.getOwnPropertyDescriptor(object, property)
o Similar to Object.getOwnPropertyDescriptor(). Returns a
property descriptor of the given property if it exists on the
object, undefined otherwise.
o If the target argument to this method is not an object (a
primitive), then it will cause a TypeError.
With Object.getOwnPropertyDescriptor, a non-object first
argument will be coerced to an object at first.
Reflect.getOwnPropertyDescriptor('foo', 0)
// TypeError: "foo" is not non-null object

Object.getOwnPropertyDescriptor('foo', 0)
// { value: "f", writable: false, enumerable: true, configurable: false }

8. Reflect.getPrototypeOf(object)
o Same as Object.getPrototypeOf().

129
9. Reflect.setPrototypeOf(object, prototype)
o A function that sets the prototype of an object. Returns
a Boolean that is true if the update was successful, false
otherwise.

10. Reflect.has(object, property)


o Returns a Boolean indicating whether the target has the
property. Either as own or inherited. Works like
the in operator as a function.

Reflect.has({x: 0}, 'x') // true

11. Reflect.isExtensible(object)
o Same as Object.isExtensible(). Returns a Boolean that is true if
the target is extensible.

12. Reflect.preventExtensions(object)
o Similar to Object.preventExtensions(). Returns a Boolean that
is true if the update was successful, false otherwise.

13. Reflect.ownKeys(object)
o Returns an array of the target object's own (not inherited)
property keys.
o Its return value is equivalent
to Object.getOwnPropertyNames(object).concat(Object.getO
wnPropertySymbols(object)).
Reflect.ownKeys({z: 3, y: 2, x: 1}) // [ "z", "y", "x" ]

130
Math Object
- The JavaScript Math object allows you to perform mathematical
tasks on numbers.
Math.PI; // returns 3.141592653589793

- Math is a global object. The new keyword cannot be used on it.

Math Constructor
- Unlike other global objects, the Math object has no constructor.
Methods and properties are static. Done without creating an object.

Math.round()
- Math.round(x) returns the value of x rounded to its nearest integer.
- It rounds negative values with decimal equal to -0.5 to the next
integer in the direction of +∞.

Math.round(-1.5) // return -1

Math.pow()
- Math.pow(base, exponent) returns the base to the exponent power, that
is, baseexponent.
- If the base is negative and the exponent is not an integer, the result
is NaN. Other cases work.

Math.sqrt()
- Math.sqrt(x) returns the square root of x.
- If the value of x is negative, it returns NaN.

Math.abs()
- Math.abs(x) returns the absolute (positive) value of x.
- Passing an empty object, an array with more than one member, a
non-numeric string or undefined/empty variable returns NaN.
Passing null, an empty string or an empty array returns 0.

Math.ceil()

131
- Math.ceil(x) returns the value of x rounded up to its nearest
integer.
- if x is null, it returns 0 and does not give a NaN error.

Math.floor()

- Math.floor(x) returns the value of x rounded down to its nearest


integer.

Math.sin()
- Math.sin(x) returns the sine (a value between -1 and 1) of the angle
x (given in radians).

Math.cos()
- Math.cos(x) returns the cosine (a value between -1 and 1) of the
angle x (given in radians).

If you want to use degrees instead of radians, you have to convert degrees
to radians:
Angle in radians = Angle in degrees x PI / 180.

Math.min() and Math.max()


- Math.min() and Math.max() can be used to find the lowest or highest
value in a list of arguments.

Math.min(0, 150, 30, 20, -8, -200); // returns -200

- If at least one of the arguments cannot be converted to a


number, NaN is returned.
- min without arguments, return Infinity and max will return -
Infinity, because it’s the default comparable value.

Math.random()
- Math.random() returns a random floating number between 0
(inclusive) and 1 (exclusive).

Math.trunc() → ES6
- The Math.trunc(value) method returns the integer part of a number.

132
- Note: This method will NOT round the number up/down to the
nearest integer, but simply remove the decimals.

Math.cbrt() → ES6
- The Math.cbrt(value) method returns the cubic root of a number.

Math.sign() → ES6
- Math.sign(value) method determine the sign of a number, including
special cases of signed zero and non-number.

Math Properties (Constants)


Math.E // returns Euler's number
Math.PI // returns PI
Math.SQRT2 // returns the square root of 2
Math.SQRT1_2 // returns the square root of 1/2
Math.LN2 // returns the natural logarithm of 2
Math.LN10 // returns the natural logarithm of 10
Math.LOG2E // returns base 2 logarithm of E
Math.LOG10E // returns base 10 logarithm of E

Complete Math object reference.

133
Random
- Always returns a number lower than 1.

A Proper Random Function


- between min (included) and max (excluded)

function getRndInteger(min, max) {


return Math.floor(Math.random() * (max - min) ) + min;
}

- between min and max (both included)

function getRndInteger(min, max) {


return Math.floor(Math.random() * (max - min + 1) ) + min;
}

- Explain why this formula here.

134
Comparison & Logical Operators
Comparison Operators
- Comparison operators are used in logical statements to determine
equality or difference between variables or values.

Operator Description

== equal to

=== equal value and equal type “strict equal”

!= not equal

!== not equal value OR not equal type

> greater than

< less than

>= greater than or equal to

<= less than or equal to

Logical Operators
- Logical operators are used to determine the logic between variables
or values.
- Logical operators in JavaScript, unlike operators in other
programming languages, do not return true or false. They always
return one of the operands.

Operator Description

&& and

|| or

! not

Conditional (Ternary) Operator


- JavaScript also contains a conditional operator that assigns a value to
a variable based on some condition.
variablename = (condition) ? value1:value2

135
Binary Logical Operators
And (&&)
- If the first operand is falsy, return it. Otherwise, return the second
operand.

console.log(NaN && 'abc'); // NaN


console.log(123 && 'abc'); // abc

Or (||)
- If the first operand is truthy, return it. Otherwise, return the second
operand.

console.log('abc' || 123); // abc


console.log('' || 123); // 123

Comparing Different Types


- Comparing data of different types may give unexpected results.
- When comparing a string with a number, JavaScript will convert the
string to a number when doing the comparison.
o An empty string converts to 0.
o A non-numeric string converts to NaN which is always false.
o When comparing two strings, "2" will be greater than "12",
because (alphabetically) 1 is less than 2.

136
Conditions
Conditional Statements
- you want to perform different actions for different decisions. You can
use conditional statements in your code to do this.
- In JavaScript we have the following conditional statements:

1. The if Statement
▪ Use the if statement to specify a block of JavaScript code to be
executed if a condition is true.

if (condition) {
// executed if the condition is true
}

▪ if is lower case not If or IF which will cause an error.

2. The else Statement


▪ Use the else statement to specify a block of code to be
executed if the condition is false.

if (condition) {
// executed if the condition is true
} else {
// executed if the condition is false
}

3. The else if Statement


▪ Use the else if statement to specify a new condition if the
first condition is false.
if (condition1) {
// executed if condition1 is true
} else if (condition2) {
// executed if the condition1 is false and condition2 is true
} else {
// executed if the condition1 is false and condition2 is false
}

137
4. The switch Statement
▪ Use the switch statement to select one of many code blocks to
be executed.

switch(expression) {
case x:
// code block
break;
case y:
// code block
break;
default:
// code block
}

▪ switch expression is evaluated once. The value of the


expression is compared with the values of each case. If there is
a match, the associated block of code is executed.
▪ When JavaScript reaches a break keyword, it breaks out of the
switch block. This will stop the execution of inside the block.
▪ Not necessary to break the last case in a switch block. The
block breaks (ends) there anyway.
▪ Note: If you omit the break statement, the next case will be
executed even if the evaluation does not match the case.
▪ The default keyword specifies the code to run if there is no
case match.
▪ The default case does not have to be the last case in a switch
block, but you need to add a break to end of it.

Common Code Blocks in switch


- Sometimes you want different switch cases to use the same code.

switch(expression) {
case x:
case z:
// code block
break;
case y:
case e:

138
// code block
break;
default:
// code block
}

Switching Details
- If multiple cases matches a case value, the first case is selected.
- If no matching cases are found, the program continues to
the default label.
- If no default label is found, the program continues to the
statement(s) after the switch.

Strict Comparison
- Switch cases use strict equality (===). The values must be of the
same type to match.

139
Loops
- Loops are handy, if you want to run the same code over and over
again, each time with a different value.

1. The For Loop


- loops through a block of code number of times.

for (statement 1; statement 2; statement 3) {


// code block to be executed
}

▪ Statement 1
o is executed (one time) before the execution of the code block.
o Initialize the variable used in the loop.
o It’s Optional.
for (; i < len; i++) {
// code block to be executed
}

o You can initiate many values.


for (i = 0, len = cars.length, text = ""; i < len; i++) {
// code block to be executed
}

▪ Statement 2
o defines the condition for executing the code block. It used to
evaluate the condition of the initial variable.
o It’s Optional too but you must provide a break inside the loop.
o If statement 2 returns true, the loop will start over again, if it
returns false, the loop will end.

▪ Statement 3
o executed (every time) after the code block has been executed.
o Often statement 3 increments the value of the initial variable.
o It’s Optional too but you need to add increment inside the loop.
o Statement 3 can do anything like negative increment (i--),
positive increment (i = i + 15), or anything else.

for (; i < len; ) {

140
text += cars[i] + "<br>";
i++;
}

2. The For/In Loop


▪ loops through the enumerable properties of an object.

for (x in person) {
text += person[x];
}

▪ In general, it is best not to add, modify or remove properties from


the object during iteration.
▪ More like for debugging purpose.

3. The For/Of Loop → ES6


▪ loops through the values of an iterable object.
▪ let’s you loop over data structures that are iterable such as Arrays,
Strings, Maps, Sets, NodeLists and more.

for (variable of iterable) {


// code block to be executed
}

▪ variable - For every iteration the value of the next property is


assigned to the variable. Variable can be declared with const, let
or var.
▪ iterable - An object that has iterable properties.

- NOTE: For/Of goes over values but For/In goes over properties
and values.

4. The While Loop


- loops through a block of code while a specified condition is true.
while (condition) {
// code block to be executed
}

141
- You need to handle the condition such as incrementing (positive or
negative).

5. The Do/While Loop


- It will execute the code block once, before checking if the condition is
true, then it will repeat the loop as long as the condition is true.

do {
// code block to be executed
}
while (condition);

- You need to handle the condition such as incrementing (positive or


negative).

Comparing For and While


- a while loop is much the same as a for loop, with statement 1 and
statement 3 omitted.
- Stop iteration using throw or break.

142
Break & Continue
The Break Statement
- used to "jump out" of a switch() statement.
- used to jump out of a loop.
- used to jump out of any code block with labels.

The Continue Statement


- can only be used to skip one loop iteration.
- breaks one iteration (in the loop). If a specified condition occurs,
continue with the next iteration in the loop.

JavaScript Labels
- To label JavaScript statements you precede (‫ )تسبق‬the statements with
a label name and a colon.
- Labels should be nested in one code block or will throw an error.

label:
{
statements;
}

- then use break or continue to jump out to statements of label.


- break with label to outerloop, will break it and stop looping.

break labelname;
continue labelname; // it’s used inside loops ONLY

- Starting with ES6, labeled function declarations are now standardized


for non-strict code. In strict mode code, this will throw
a SyntaxError.

L: function F() {}

143
Type Conversion
The Data Type of typeof
- The typeof operator is not a variable. It is an operator. Operators (
+ - * / ) do not have any data type.
- typeof is mainly used for primitive values, while instanceof is used
for objects.

var ob = {};
ob instanceof Object; // true

The constructor Property


- The constructor property returns the constructor function for all
JavaScript variables.

JavaScript Type Conversion


- JavaScript variables can be converted to a new variable and another
data type:
1. By the use of a JavaScript function.

2. Automatically by JavaScript itself.

Converting Numbers, Booleans and Dates to Strings


- The global method String() can convert numbers, Booleans and
dates to strings.
- Parameter can be direct value, literals, variables or expressions.
- The method toString() does the same.

Converting Booleans and Dates to Numbers


- The global method Number() can convert Booleans and dates to
numbers.
- For Dates, the date method getTime() does the same.

Automatic Type Conversion


- When JavaScript tries to operate on a "wrong" data type, it will try to
convert the value to a "right" type.

5 + null

144
// returns 5, because null is converted to 0
"5" + null
// returns "5null", because null is converted to "null"
"5" + 2
// returns "52", because 2 is converted to "2"
"5" - 2
// returns 3, because "5" is converted to 5
"5" * "2"
// returns 10, because "5" and "2" are converted to 5 and 2

- Notice that + used to concatenate strings if numbers and strings


there, but other mathematical operators will try to convert strings to
numbers.

Automatic String Conversion


- JavaScript automatically calls the variable's toString() function when
you try to "output" an object or a variable.

document.getElementById("demo").innerHTML = myVar;

// if myVar = {name:"Fjohn"}
// toString converts to "[object Object]"
// if myVar = [1,2,3,4]
// toString converts to "1,2,3,4"
// if myVar = new Date()
// toString converts to "Fri Jul 18 2014 09:08:55 GMT+0200"

JavaScript Type Conversion Table


Original Value Converted to Number Converted to Converted to Boolean
String

false 0 "false" false

true 1 "true" true

0 0 "0" false

1 1 "1" true

145
"0" 0 "0" true

"000" 0 "000" true

"1" 1 "1" true

NaN NaN "NaN" false

Infinity Infinity "Infinity" true

-Infinity -Infinity "-Infinity" true

"" 0 "" false

"20" 20 "20" true

"twenty" NaN "twenty" true

[] 0 "" true

[20] 20 "20" true

[10,20] NaN "10,20" true

["twenty"] NaN "twenty" true

["ten”,“twenty"] NaN "ten,twenty" true

function(){} NaN "function(){}" true

{} NaN "[object Object]" true

null 0 "null" false

undefined NaN "undefined" false

146
Bitwise Operations
JavaScript Uses 32 bits Bitwise Operands
- JavaScript stores numbers as 64 bits floating point numbers.
- Before a bitwise operation, JavaScript converts numbers to 32 bits
signed integers after that, the result converted back to 64 bits.

Bitwise AND ( & )


- It returns 1 if both bits are 1.

Operation Result

0&0 0

0&1 0

1&0 0

1&1 1

Bitwise OR ( | )
- It returns 1 if one of the bits are 1.

Operation Result

0|0 0

0|1 1

1|0 1

1|1 1

Bitwise XOR ( ^ )
- It returns 1 if the bits are different.

Operation Result

0^0 0

0^1 1

1^0 1

1^1 0

147
JavaScript Bitwise NOT ( ~ )
- Inverts all the bits.
- The result always done by –( num + 1).
~5 = -(5+1) = -6
~-6 = -(-6+1) = 5

JavaScript (Zero Fill) Bitwise Left Shift (<<)


- This is a zero fill left shift. One or more zero bits are pushed in
from the right, and the leftmost bits fall off.

5 00000000000000000000000000000101

5 << 1 00000000000000000000000000001010 (10)

JavaScript (Sign Preserving) Bitwise Right Shift (>>)


- This is a sign preserving right shift. Copies of the leftmost bit are
pushed in from the left, and the rightmost bits fall off.

-5 11111111111111111111111111111011

-5 >> 1 11111111111111111111111111111101 (-3)

JavaScript (Zero Fill) Right Shift (>>>)


- This is a zero fill right shift. One or more zero bits are pushed in
from the left, and the rightmost bits fall off.

5 00000000000000000000000000000101

5 >>> 1 00000000000000000000000000000010 (2)

Binary Numbers
- JavaScript binary numbers are stored in two's complement format.
This means that a negative number is the bitwise NOT of the
number plus 1.
5 → 00000000000000000000000000000101 to get -5
~5 → 11111111111111111111111111111010 = -6
Then plus 1 to it which is XOR
1111111111111111111111111111010
00000000000000000000000000000001

148
-5 → 1111111111111111111111111111011

Converting Decimal to Binary


function dec2bin(dec){
return (dec >>> 0).toString(2);
}

Converting Binary to Decimal


function bin2dec(bin){
return parseInt(bin, 2).toString(10);
}

149
Regular Expressions
- A regular expression is a sequence of characters that forms a
search pattern. Used for text search or text replace.
/pattern/modifiers;
var patt = /w3schools/i;
- Note: If you want to use any special character as a part of the
expression, for example you want to match literal ), then you
have to escape them with backslash “\)”.
- () use for subexpression.

Regular Expression Modifiers

Modifier Description

i Perform case-insensitive matching

g Perform a global match (find all matches rather than


stopping after the first match)

m Perform multiline matching

Regular Expression Patterns


2. Brackets are used to find a range of characters or numbers.

Expression Description

[abc] Find any of the characters between the brackets

[^abc] Find any character NOT between the brackets

[0-9] Find any of the digits between the brackets

(x|y) Find any of the alternatives separated with |

3. Metacharacters are characters with a special meaning:

Metacharacter Description

. Find a single character, except newline or line


terminator

\w Find a word character, Same as [a-zA-Z0–9_]

150
\W Find a non-word character

\d Find a digit, same as [0-9]

\D Find a non-digit character

\s Find a whitespace character

\S Find a non-whitespace character

\b Find a match at the beginning/end of a word,


beginning like this: \bHI, end like this: HI\b

\B Find a match, but not at the beginning OR not at the


end of a word

\0 Find a NULL character

\n Find a new line character

\f Find a form feed character

\r Find a carriage return character

\t Find a tab character

\v Find a vertical tab character

\xxx Find the character specified by an octal number xxx

\xdd Find the character specified by a hexadecimal


number dd

\udddd Find the Unicode character specified by a


hexadecimal number dddd

4. Quantifiers define quantities:

Quantifier Description

n+ Matches any string that contains at least 1 n

Matches any string that contains 0 or more occurrences


n*
of n

n? Matches any string that contains 0 or 1 occurrences of n

n{X} Matches any string that contains a sequence of X n's

151
Matches any string that contains a sequence of X to
n{X,Y}
Y n's

Matches any string that contains a sequence of at


n{X,}
least X n's

n$ Matches any string with n at the end of it

^n Matches any string with n at the beginning of it

Matches any string that is followed by a specific


?=n
string n

Matches any string that is not followed by a specific


?!n
string n

Using String Methods


- In JavaScript, regular expressions are often used with the two string
methods: search() and replace().

Using the RegExp Object


- RegExp object is a regular expression object with predefined
properties and methods.
- There are two ways to create a RegExp object:
1. The literal notation's parameters are enclosed between
slashes and do not use quotation marks.

new RegExp(/ab+c/, 'i') // literal notation

▪ It’s used when the pattern is fixed.

2. The constructor function's parameters are using quotation


marks.

new RegExp('ab+c', 'i')

▪ It’s used when the pattern will change “like in a loop”.


▪ When using the constructor function, the normal
string escape rules (preceding special characters
with \ when included in a string) are necessary.

let re = /\w+/;
let re = new RegExp('\\w+');

152
RegExp Object methods
1. Using test()
▪ It searches a string for a pattern, and returns true or false,
depending on the result.

2. Using exec()
▪ It searches a string for a specified pattern, and returns the
found text as an object, if no match returns an empty object
(null).

var pos = regExp.exec(str);

▪ Returned Object structure if there is a match.


[
0: pattern,
index: value,
input: textSearchIn,
groups: undefined
]

RegExp Object Properties

Property Description

constructor Returns the function that created the RegExp object's


prototype

global Checks whether the "g" modifier is set

ignoreCase Checks whether the "i" modifier is set

lastIndex Specifies the index at which to start the next match

multiline Checks whether the "m" modifier is set

source Returns the text of the RegExp pattern

Complete RegExp Reference.

Complete RegExp Reference MDN.

Pattern to Learn from.

153
Errors
1. The try statement lets you test a block of code for errors.
2. The catch statement lets you handle the error.
3. The throw statement lets you create custom errors.
4. The finally statement lets you execute code, after try and catch,
regardless of the result.

The JavaScript statements try and catch come in pairs.


try {
//Block of code to try
}
catch(err) {
//Block of code to handle errors
}

Optional Catch Binding → ES10


- In the past catch clause from a try/catch statement required a
variable. Now it allows developers to use try/catch without creating
an unused binding.

//Before ES10
try {
undefined_Function("I'm trying");
} catch(error) {
console. log('action' );
}
// ES10
try {
undefined_Function("I'm trying");
} catch {
console. log('action' );
}

JavaScript Throws Errors

154
- When an error occurs, JavaScript will normally stop and generate an
error message.
- The technical term for this is: JavaScript will throw an exception
(throw an error).
- The throw statement allows you to create a custom error.
- The exception can be a String, a Number, a Boolean or an Object.

If you use throw together with try and catch, you can control program flow
and generate custom error messages.

try {
if(x == "") throw "empty";
if(isNaN(x)) throw "not a number";
}
catch(err) {
message.innerHTML = "Input is " + err;
}

The finally Statement


- The finally statement lets you execute code, after try and catch,
regardless of the result.

try {
//Block of code to try
}
catch(err) {
//Block of code to handle errors
}
finally {
//Block of code to be executed regardless of the try / catch result
}

The Error Object


- JavaScript has a built in error object that provides error information
when an error occurs.

Error Object Properties

155
Property Description

name Sets or returns an error name

message Sets or returns an error message (a string)

throw new Error('Required'); //message parameter

Error Name Values


- 6 different values can be returned by the error name property:

Error Name Description

EvalError On eval(), In newer JS versions, it use


SyntaxError
if you use a number that is outside the range
RangeError
of legal values
ReferenceError An illegal reference has occurred, if you use a
variable that not declared.

SyntaxError A syntax error has occurred

TypeError A type error has occurred

URIError (Uniform Resource An error in encodeURI() has occurred


Identifier)

156
Use Strict → ES5
The "use strict" Directive
- The "use strict" directive was new in ES5.
- Used to indicate that the code should be executed in "strict mode".
- All modern browsers support "use strict" except Internet Explorer 9
and lower.
- It helps you to write cleaner code.

Declaring Strict Mode


- Strict mode is declared by adding "use strict"; to the beginning of
a script or a function.
- It has global scope (all code in the script will execute in strict mode).

The "use strict"; Syntax


- The syntax, for declaring strict mode, was designed to be compatible
with older versions of JavaScript. So "use strict"; only matters to
new compilers that "understand" the meaning of it.

Why Strict Mode?


- Strict mode makes it easier to write "secure" JavaScript. It convert
"bad syntax" into real errors.
- As an example, in normal JavaScript, mistyping a variable name
creates a new global variable. In strict mode, this will throw an error,
making it impossible to accidentally create a global variable.

Not Allowed in Strict Mode


1. Using a variable, without declaring it, is not allowed.
2. Deleting a variable (or object) is not allowed.
3. Deleting a function is not allowed.
4. Duplicating a parameter name is not allowed.
5. Octal numeric literals are not allowed.
var x = 010; // This will cause an error

6. Octal escape characters are not allowed.


7. Writing to a read-only property is not allowed.
8. Writing to a get-only property is not allowed.

157
9. Deleting an undeletable property is not allowed.
10. The word eval cannot be used as a variable.
11. The word arguments cannot be used as a variable.
12. The with statement is not allowed.
13. For security reasons, eval() is not allowed to create variables in
the scope from which it was called.
14. Requires that all properties named in an object literal be unique.
15. The this keyword in functions behaves differently in strict mode.
It refers to the object that called the function. If the object is not
specified, functions in strict mode will return undefined and
functions in normal mode will return the global object (window).

Future Proof!
o Keywords reserved for future JavaScript versions can NOT be used as
variable names in strict mode:
• implements
• interface
• let
• package
• private
• protected
• public
• static
• yield

158
Classes → ES6
- A class is a type of function, but instead of using the
keyword function to initiate it, we use the keyword class and the
properties are assigned inside a constructor() method.

Class Definition
- Use the keyword class to create a class and always add
the constructor() method.
- The constructor method is called each time the class object is
initialized.

class Car {
constructor(brand) {
this.carname = brand;
}
}
mycar = new Car("Ford");

Methods
- The constructor method is special, in fact, if you do not have a
constructor method, JavaScript will add an invisible and
empty constructor method.
- You are also free to make your own methods.

class Car {
constructor(brand) {
this.carname = brand;
}
present() {
return "I have a " + this.carname;
}
}
mycar = new Car("Ford");
let car = mycar.present();

Static Methods

159
- Static methods are defined on the class itself and not on the
prototype.
- That means you can’t call a static method on the object (mycar), but
on the class (Car).

class Car {
constructor(brand) {
this.carname = brand;
}
static hello() { // x
return "Hello!!"; // x.carname;
}
}

//Call 'hello()' on the class Car:


document.getElementById("demo").innerHTML = Car.hello();

- If you want to use the mycar object inside the static method, you can
send it as a parameter.

document.getElementById("demo").innerHTML = Car.hello(mycar);

Private Class Variables → ES11


- By adding a simple hash symbol “#” in front of our variable or
function, we can reserve them entirely for internal use inside the
class.

class Person {
#born = 1980;
age() { console.log(2020 - this.#born); }
}
const person1 = new Person();
person1.age(); // 40
console.log(person1.#born); //Uncaught SyntaxError: Private field '#born' must be declared
in an enclosing class

Inheritance
- To create a class inheritance, use the extends keyword.

160
- A class created with a class inheritance, inherits all the methods from
another class.

class Car {
constructor(brand) {
this.carname = brand;
}
present() {
return 'I have a ' + this.carname;
}
}

class Model extends Car {


constructor(brand, mod) {
super(brand);
this.model = mod;
}
show() {
return this.present() + ', it is a ' + this.model;
}
}

- The super() method refers to the parent class. By calling it in the


constructor method, we call the parent's constructor method and gets
access to the parent's properties and methods.
- Inheritance useful for code reusability, reuse of properties and
method of existing class.

Getters and Setters


- It can be smart to use getters and setters for your properties,
especially if you want to do something special with the value before
returning them or before you set them.
- To add getters and setters in the class, use
the get and set keywords.

class Car {
constructor(brand) {
this.carname = brand;

161
}
get cnam() {
return this.carname;
}
set cnam(x) {
this.carname = x;
}
}

mycar = new Car("Ford");


document.getElementById("demo").innerHTML = mycar.cnam;

- Even get is a function, no need for parentheses () when you use it.
- The name of the getter/setter method can’t be the same as the
name of the property. So we can use an underscore
character _ before the property name to separate the getter/setter
from the actual property.

class Car {
constructor(brand) {
this._carname = brand;
}
get carname() {
return this._carname;
}
}

- To use a setter, use the same syntax as when you set a property
value, without parentheses ().

class Car {
constructor(brand) {
this._carname = brand;
}
get carname() {
return this._carname;
}

162
set carname(x) {
this._carname = x;
}
}

mycar = new Car("Ford");


mycar.carname = "Volvo";

Key Points to remember about Classes


- Unlike functions, classes are not hoisted. A class cannot be used
before it is declared.
- A class can inherit properties and methods from other classes by
using the extend keyword.
- All the syntaxes inside the class must follow the strict mode ‘use
strict’ of JavaScript. Error will be thrown if the strict mode rules are
not followed.

163
Modules → ES6
- A module is a reusable piece of code that encapsulates
implementation details and exposes a public API so it can be easily
loaded and used by other code.
- A module format is the syntax we use to define a module. Different
module formats
such AMD, CommonJS, UMD and System.register have emerged in
the past and a native module format is now available since ES6.
- A module loader interprets and loads a module written in a certain
module format at runtime. Popular examples
are RequireJS and SystemJS.
- A module bundler replaces a module loader and generates a bundle
of all code at build time. Popular examples
are Browserify and Webpack.

Module basics
- An ES6 module is a file containing JS code which is a small unit of
independent, reusable code. There’s no special module keyword; a
module mostly reads just like a script.
- What should know about ES6 Modules.
• ES6 modules are automatically strict-mode code, even if you
don’t write "use strict".
• You can use import and export in modules.
• Modules must be included in your HTML with type="module",
which can be an inline or external script tag.
• Modules are deferred and only run after a document is
loaded.
- ES6 modules is a very powerful concept, although support is not
available everywhere yet, a common way of using it is to transpile
into ES5. You can use Grunt, Gulp, Webpack, Babel or some other
transpiler to compile the modules during a build process.

Export Modules
- Everything declared inside a module is local to the module, by
default. If you want something declared in a module to be public, so
that other modules can use it, you must export that feature. There
are a few ways to do this.
1. You can export each module individually.

export let sumAll = (a, b) => {return a + b;}

164
export let subtractAll = (a, b) => {return a - b;}
export let divideAll = (a, b) => {return a / b;}
export let multiplyAll = (a, b) => {return a * b;}
export let findModulus = (a, b) => {return a % b;}

2. A better way is to use a single export statement.

let sumAll = (a, b) => {return a + b;}


let subtractAll = (a, b) => {return a - b;}
let divideAll = (a, b) => {return a / b;}
let multiplyAll = (a, b) => {return a * b;}
let findModulus = (a, b) => {return a % b;}
export {sumAll, subtractAll, divideAll, multiplyAll, findModulus};

• An export list doesn’t have to be the first thing in the file;


it can appear anywhere in a module file’s top-level scope.
You can have multiple export lists or mix export lists with
other export declarations, as long as no name is exported
more than once.
3. You can export modules as aliases.

function v1() { /* ... */ }


function v2() { /* ... */ }

export { v1 as streamV1, v2 as streamV2, v2 as streamLatestVersion };

• This is handy if you want to export the same value under


two different names, which occasionally happens.
4. You can also export default values.

export default {sumAll, subtractAll, multiplyAll, divideAll};

• The keywords export default can be followed by any


value: a function, a class, an object literal, you name it.
• You can do export default one time in each module.

- You can export any top-level function, class, var, let or const.

Import Modules
- In a separate file, we can import and use exported things. It can be
done in several ways.
1. You can import individually.

165
import { sumAll } from "./math.js";

2. You can import multiple modules at once.

import {sumAll, subtractAll, divideAll} from './math.js';

3. You can import modules as aliases.

import * as math from './math.js';


console.log(math.sumAll(50, 10)); // 60

• When you import *, what’s imported is a module


namespace object.
4. You can also import default values.

import math from './math.js';


console.log(math.sumAll(5, 2)); // 7

• This way is a shorthand for


import {default as math} from.
• If you don’t export as default and you import using this
method, you will get this error:

Uncaught SyntaxError: The requested module './math.js' does not


provide an export named 'default'

Modules Path References


- Modules are imported with either absolute or relative references
and must start with either “/”, “./” or “../”
- You can also use an absolute path for the module import, to
reference modules defined on another domain.

import {sumAll} from 'https://bolaji-module.glitch.me/sumAll.js';


console.log(sumAll(50, 10)); // 60

Aggregating modules
- Sometimes the main module of a package is little more than
importing all the package’s other modules and exporting them in a
unified way. To simplify this kind of code, there’s an all-in-one
import-and-export shorthand.

// world-foods.js - good stuff from all over

// import "sri-lanka" and re-export some of its exports


export {Tea, Cinnamon} from "sri-lanka";

166
// import "equatorial-guinea" and re-export some of its exports
export {Coffee, Cocoa} from "equatorial-guinea";

// import "singapore" and export ALL of its exports


export * from "singapore";

- Each one of these export-from statements is similar to an import-


from statement followed by an export.
- Unlike a real import, this doesn’t add the re-exported bindings to
your scope. So don’t use this shorthand if you plan to write some
code in world-foods.js that makes use of Tea. You’ll find that it’s not
there.
- If any name exported happened to collide with the other exports, that
would be an error, so use export * with care.

What does import actually do?


- Would you believe… nothing?
- ES6 leaves the details of module loading entirely up to the
implementation.
- When you tell the JS engine to run a module, it has to behave as
though these four steps are happening:

1. Parsing: The implementation reads the source code of the


module and checks for syntax errors.
2. Loading: The implementation loads all imported modules
(recursively).
3. Linking: For each newly loaded module, the implementation
creates a module scope and fills it with all the bindings declared
in that module, including things imported from other modules.
4. Run time: Finally, the implementation runs the statements in the
body of each newly-loaded module. By this
time, import processing is already finished, so when execution
reaches a line of code where there’s an import declaration…
nothing happens!

- Because the system doesn’t specify how loading works and because
you can figure out all the dependencies, an implementation of ES6 is
free to do all the work at compile time and bundle all your modules
into a single file to ship them over the network. Tools like webpack
does that.
- This is a big deal, because loading scripts over the network takes
time and every time you fetch one, you may find that it

167
contains import declarations that require you to load dozens more. A
naive loader would require a lot of network round trips.
- Modules are singletons. Even if a module is imported multiple times,
only a single “instance” of it exists.

JS use Static Module System


- For a dynamic language, JavaScript has gotten itself a surprisingly
static module system.
• All flavors of import and export are allowed only at top-level in a
module.
o There are no conditional imports or exports and you can’t
use import in function scope.

• All exported identifiers must be explicitly exported by name in the


source code.
o You can’t programmatically loop through an array and export
a bunch of names in a data-driven way.

• Module objects are frozen.


o There is no way to hack a new feature into a module object,
polyfill style.

• All of a module’s dependencies must be loaded, parsed and linked


eagerly, before any module code runs.
o There’s no syntax for an import that can be loaded lazily,
on demand.

• There is no error recovery for import errors.


o An app may have hundreds of modules in it and if anything
fails to load or link, nothing runs. You can’t import in
a try/catch block. (The upside here is that because the
system is so static, webpack can detect those errors for you
at compile time.)

• There is no hook allowing a module to run some code before its


dependencies load.
o This means that modules have no control over how their
dependencies are loaded.

How to use Dynamic Module System


- That’s why whatever module-loading system you use, you will have a
programmatic API to go alongside ES6’s static import/export syntax.
- For example, webpack includes an API that you can use for “code
splitting”, loading some bundles of modules lazily on demand. The
same API can help you break most of the other rules listed above.

168
- The ES6 module syntax is very static and that’s good—it’s paying off
in the form of powerful compile-time tools. But the static syntax was
designed to work alongside a rich dynamic, programmatic loader API.

Dynamic import → ES10


- Dynamic import() returns a promise for the module namespace
object of the requested module. Therefore, imports can now be
assigned to a variable using async/await.

// Option 1
const moduleSpecifier = './utils.js';
import (moduleSpecifier)
.then((module) => {
module.doStuff1( ) ; // Method-1
module.doStuff2( ) ; // Method-2
});

// Option 2 - using async/await


(async function( ){
const moduleSpecifier = './utils.js';
const module =
await import(moduleSpecifier);
module.doStuff1(); // Method-1
module.doStuff2(); // Method-2
})();

Resources:
- Modules.

169
JavaScript Async
1. Callbacks
- It is a function passed as an argument to another function.
- This technique allows a function to call another function, a callback
function can run after another function has finished.

Function Sequence
- JavaScript functions are executed in the sequence they are called.
Not in the sequence they are defined.

function myDisplayer(some) {
document.getElementById("demo").innerHTML = some;
}

function myCalculator(num1, num2, myCallback) {


let sum = num1 + num2;
myCallback(sum);
}

myCalculator(5, 5, myDisplayer);

- NOTE: When you pass a function as an argument, remember not to


use parenthesis.

When to Use a Callback?


- In asynchronous functions, where one function has to wait for
another function (like waiting for a file to load).

2. Asynchronous JavaScript
- Functions running in parallel with other functions are called
asynchronous.
- When using the JavaScript function setTimeout(), you can specify a
callback function to be executed on time-out.

setTimeout(myFunction, 4000);

function myFunction() {

170
document.getElementById("demo").innerHTML = "I love You !!";
}

3. Promises → ES6
- "I promise a result!"
- "Producing code" is code that can take some time.
- "Consuming code" is code that must wait for the result, functions
want the result of the “producing code” once it’s ready.
- A promise is a JavaScript object that links producing code and
consuming code. The “producing code” takes whatever time it needs
to produce the promised result and the “promise” makes that result
available to all of the subscribed code when it’s ready.
- Promises done ONE time, accepting first value.
let promise = new Promise(function(resolve, reject) {
// The producing code (it may takes some time)

resolve(); // when successful


reject(); // when error
});

- When the executing code obtains the result, it should call one of the
two callbacks.

Result Call

Success resolve(result value)

Error reject(error object)

Promise Object Properties


- The Promise object supports two properties: state and result.
- A JavaScript Promise object can contains one state:
▪ Pending
▪ Fulfilled
▪ Rejected
- While a Promise object state is "pending" (working), the result
is undefined.
- When a Promise object state is "fulfilled", the result is a value.

171
- When a Promise object state is "rejected", the result is an
error object.

Consumers: then, catch, finally


then
- The first argument of .then is a function that runs when the
promise is resolved and receives the result.
- The second argument of .then is a function that runs when the
promise is rejected and receives the error.
- Both are optional and you can handle one of them.
promise.then(
function(result) { /* handle a successful result */ },
function(error) { /* handle an error */ }
);

catch
- If we’re interested only in errors, then we can use null as the
first argument: .then(null, errorHandlingFunction). Or we
can use .catch(errorHandlingFunction), which is exactly the
same.
finally
- The call .finally(f) is similar to .then(f, f) in the sense
that f always runs when the promise is settled: resolve or reject.

172
- finally is a good handler for performing cleanup, e.g. stopping
our loading indicators, as they are not needed anymore, no
matter what the outcome is.
- A finally handler has no arguments.
- A finally handler passes results and errors to the next handler.

promise
.then(
function(result) { /* handle successful result */ },
function(error) { /* handle an error */ }
)
.finally(()=>{ /*do it doesn’t matter the result */ });

Chaining
- A common need is to execute two or more asynchronous
operations back to back, where each subsequent operation starts
when the previous operation succeeds, with the result from the
previous step. We accomplish this by creating a promise chain.
doSomething()
.then(function(result) {
return doSomethingElse(result);
})
.then((newResult) => doThirdThing(newResult))
.then(function(finalResult) {
console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);

- Important: Always return results, otherwise callbacks won't


catch the result of a previous promise.

Promise rejection events


- Whenever a promise is rejected, one of two events is sent to the
global scope (generally, this is either the window or if being
used in a web worker) The two events are:
1. Rejectionhandled

173
▪ Sent when a promise is rejected, after that rejection
has been handled by the executor's reject function.
2. unhandledrejection
▪ Sent when a promise is rejected but there is no
rejection handler available.
- In both cases, the event (of type PromiseRejectionEvent) has
a promise property indicating the promise that was rejected,
and a reason property that provides the reason given for the
promise to be rejected.
- These make it possible to offer fallback error handling for
promises, as well as to help debug issues with your promise
management. These handlers are global per context, so all
errors will go to the same event handlers, regardless of source.
- You can handle unhandled promises by adding a handler for
the unhandledrejection event.

window.addEventListener("unhandledrejection", event => {


/* You might start here by adding code to examine the
promise specified by event.promise and the reason in
event.reason */

event.preventDefault();
}, false);

- By calling the event's preventDefault() method, you tell the


JavaScript runtime not to do its default action when rejected
promises go unhandled. That default action usually involves
logging the error to console and this is indeed the case for Node.

Composition
- Promise.resolve() and Promise.reject() are shortcuts to
manually create an already resolved or rejected promise
respectively.
- Promise.all() and Promise.race() are two composition tools
for running asynchronous operations in parallel.

Nesting
- Nesting is a control structure to limit the scope
of catch statements. Specifically, a nested catch only catches
failures in its scope and below, not errors higher up in the chain
outside the nested scope. When used correctly, this gives
greater precision in error recovery.

174
doSomethingCritical()
.then(result => doSomethingOptional(result)
.then(optionalResult => doSomethingExtraNice(optionalResult))
.catch(e => {})
) // Ignore if optional stuff fails; proceed.
.then(() => moreCriticalStuff())
.catch(e => console.error("Critical failure: " + e.message));

- The inner neutralizing catch statement only catches failures


from doSomethingOptional() and doSomethingExtraNice(),
after which the code resumes with moreCriticalStuff().
Importantly, if doSomethingCritical() fails, its error is caught
by the final (outer) catch only.

Promise Static Methods


1. Promise.all
▪ Method takes an iterable of promises as an input and
returns a single Promise that resolves to an array of the
results of the input promises.
▪ Used if the tasks are dependent on each other.
▪ Returned promise will resolve when all of the input's
promises have resolved (includes non-promises values). If
the iterable is empty, returned value is an empty array
and run sync.
▪ It rejects immediately upon any of the input promises
rejecting or non-promises throwing an error and will
reject with this first rejection message / error.
▪ Returned values will be in order of the Promises passed,
regardless of completion order.
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
}); // expected output: Array [3, 42, "foo"]

2. Promise.allSettled → ES11
▪ A method returns a promise that resolves after all of the
given promises have either fulfilled or rejected, with an
array of objects that each describes the outcome of each
promise.
▪ It is typically used when you have multiple asynchronous
tasks that are not dependent on one another to

175
complete successfully or you'd always like to know the
result of each promise.
▪ If the iterable is empty, returned value is an empty array
and run sync.

Promise.allSettled([
Promise.resolve(33),
new Promise(resolve => setTimeout(() => resolve(66), 0)),
99,
Promise.reject(new Error('an error'))
])
.then(values => console.log(values));

// [
// {status: "fulfilled", value: 33},
// {status: "fulfilled", value: 66},
// {status: "fulfilled", value: 99},
// {status: "rejected", reason: Error: an error}
// ]

3. Promise.any
▪ Takes an iterable of Promise objects and as soon as one
of the promises in the iterable fulfills, returns a single
promise that resolves with the value from that promise.
▪ If no promises in the iterable fulfill (if all of the given
promises are rejected), then the returned promise is
rejected with an AggregateError, a new subclass
of Error that groups together individual errors. Essentially,
this method is the opposite of Promise.all().
▪ Return an already rejected Promise if
the iterable passed is empty.
▪ Return an asynchronously resolved Promise if
the iterable passed contains no promises.
▪ This method is useful for returning the first promise that
fulfills.
▪ This method returns the first fulfilled value. This method
will ignore all rejected promises up until the first promise
that fulfils.

const pErr = new Promise((resolve, reject) => {

176
reject("Always fails");
});

const pSlow = new Promise((resolve, reject) => {


setTimeout(resolve, 500, "Done eventually");
});

const pFast = new Promise((resolve, reject) => {


setTimeout(resolve, 100, "Done quick");
});

Promise.any([pErr, pSlow, pFast]).then((value) => {


console.log(value);
// pFast fulfils first
})
// expected output: "Done quick"

4. Promise.race
▪ A method returns a promise that fulfills or rejects as soon
as one of the promises in an iterable fulfills or rejects,
with the value or reason from that promise.
▪ If the iterable passed is empty, the promise returned will
be forever pending.
▪ If the iterable contains one or more non-promise value
and/or an already settled promise, then Promise.race will
resolve to the first of these values found in the iterable.

var resolvedPromisesArray = [Promise.resolve(33),


Promise.resolve(44)];

var p = Promise.race(resolvedPromisesArray);
// immediately logging the value of p
console.log(p);
// setTimeout to execute code after stack is empty
setTimeout(function(){
console.log('the stack is now empty');
console.log(p);

177
});

// logs, in order:
// Promise { <state>: "pending" }
// the stack is now empty
// Promise { <state>: "fulfilled", <value>: 33 }

4. JavaScript Async/Await → ES8


- Async and await make promises easier to write.
- The keyword async before a function ensures that function
returns a promise and wraps non-promises in it.

async function f() {


return "Hello";
}

- Same as:

async function f() {


return Promise.resolve("Hello");
}

- The keyword await before a function makes the function wait for
a promise.

let value = await promise;

- The await keyword can only be used inside


an async function.
- Async functions can contain zero or more await expressions.
Await expressions suspend progress through an async function,
yielding control and subsequently resuming progress only when
an awaited promise-based asynchronous operation is either
fulfilled or rejected. The resolved value of the promise is treated
as the return value of the await expression. Use
of async/await enables the use of ordinary try/catch blocks
around asynchronous code.
- The purpose of async/await is to simplify the syntax necessary
to consume promise-based APIs. The behavior of async/await is
similar to combining generators and promises.

178
Proxy → ES6
- Throughout the ES6 standard, wherever possible, any bit of syntax or
built-in function that does anything with objects is specified in terms
of the 14 internal methods. ES6 drew a clear boundary around the
brains of an object. What proxies let you do is, replace the standard
kind of brains with arbitrary JS code.
- When we start talking about overriding these internal methods in a
moment, remember, we’re talking about overriding the behavior of
core syntax like obj.prop, built-in functions like Object.keys() and
more.
- ES6 defines a new global constructor, Proxy. It takes two arguments:
a target object and a handler object.

var target = {}, handler = {};


var proxy = new Proxy(target, handler);

- Focusing on how proxy and target are related. In this example, all
of proxy’s internal methods are forwarded to target. That is, if
something calls proxy.[[Enumerate]](), it’ll just
return target.[[Enumerate]]().
- We’ll do something that causes proxy.[[Set]]() to be called.

proxy.color = "pink";

- proxy.[[Set]]() should have called target.[[Set]](), so that should


have made a new property on target.
target.color; //"pink"

- It did. And the same goes for all the other internal methods. This
proxy will, for the most part, behave exactly the same as its target.
- There are limits to the fidelity (‫ )االخالص‬of the illusion. You’ll find
that proxy !== target and a proxy will sometimes flunk (‫ )يفشل‬type
checks that the target would pass. Even if a proxy’s target is a DOM
Element, for example, the proxy isn’t really an Element; so
something like document.body.appendChild(proxy) will fail with
a TypeError.

Proxy handlers
- The handler object’s methods can override any of the proxy’s internal
methods.
- Handler functions are sometimes called traps, presumably because
they trap calls to the target object.

179
- For example, if you’d like to intercept all attempts to assign to an
object’s properties, you can do that by defining
a handler.set() method.

var target = {};


var handler = {
set: function (target, key, value, receiver) {
throw new Error("Please don't set properties on this object.");
}
};
var proxy = new Proxy(target, handler);

- With the help of the Reflect class we can give some accessors the
original behavior and redefine others. Arguments are the same
arguments (target, prop, receiver) that pass to the get function.
const target = {
message1: "hello",
message2: "everyone"
};

const handler3 = {
get: function (target, prop, receiver) {
if (prop === "message2") {
return "world";
}
return Reflect.get(...arguments);
},
};

const proxy3 = new Proxy(target, handler3);

console.log(proxy3.message1); // hello
console.log(proxy3.message2); // world

- The receiver argument provided value of this for the call to target.
When used with Proxy, it can be an object that inherits from target.
- All handler methods are optional. If an internal method is not
intercepted by the handler, then it’s forwarded to the target, as we
saw before.

180
- All Proxy Handlers from MDN.

Static Methods
Proxy.revocable(target, handler)
- A method used to create a revocable Proxy object.
▪ target: an object to wrap with Proxy. It can be any sort of
object, including a native array, a function or even another
proxy.
▪ handler: an object whose properties are functions define the
behavior of proxy when an operation is performed on it.

- A revocable Proxy is an object with following two


properties {proxy: proxy, revoke: revoke}.
- revoke() is a function with no argument to invalidate (switch
off) the proxy. If the revoke() function gets called, the proxy
becomes unusable: Any trap to a handler will throw
a TypeError. Once a proxy is revoked, it will remain revoked
and can be garbage collected. Calling revoke() again has no
effect.

var revocable = Proxy.revocable({}, {


get: function(target, name) {
return "[[" + name + "]]";
}
});
var proxy = revocable.proxy;
console.log(proxy.foo); // "[[foo]]"

revocable.revoke();

console.log(proxy.foo); // TypeError is thrown


proxy.foo = 1 // TypeError again
delete proxy.foo; // still TypeError
typeof proxy // "object", typeof doesn't trigger any trap

181
Web Geolocation API
- Here details link

182
Event loop: Microtasks and Macrotasks
- Browser JavaScript execution flow, as well as in Node.js, is based on
an event loop.

Event Loop
- The event loop concept is very simple. There’s an endless loop, where
the JavaScript engine waits for tasks, executes them and then
sleeps, waiting for more tasks.
- The general algorithm of the engine:
1. While there are tasks.

2. execute them, starting with the oldest task.

3. Sleep until a task appears, then go to 1.

- That’s a formalization for what we see when browsing a page. Tasks


are set – the engine handles them – then waits for more tasks.
- It may happen that a task comes while the engine is busy, then it’s
enqueued.
- Tasks from the queue are processed on “first come – first served”
basis.

Task
- A task is any JavaScript code which is scheduled to be run by the
standard mechanisms.
- Task can be Sync or Async.
- Sync tasks executed directly without enqueued them → Call Stack
- Async tasks are:
1. Macrotask → Task Queue
- Those tasks (their callbacks functions) are enqueued in Macrotask
Queue: setTimeout, setInterval, setImmediate,
requestAnimationFrame, I/O, UI Rendering.
2. Microtask → Job Queue
- Those tasks are enqueued in Microtask Queue: promises an
execution of .then/catch/finally handler. await as well, as it’s
another form of promise handling.
- There’s also a special function queueMicrotask(func) that
queues functions for execution in the microtask queue.
- MutationObserver is another microtask. Check here.

183
How JS engine handle Tasks:
- Immediately after every macrotask, the engine executes all
tasks from microtask queue, prior to running any other
macrotasks or rendering or anything else.
- A more detailed event loop algorithm:
1. Dequeue and run the oldest task from the macrotask queue.
a. Execute all microtasks:
i. While the microtask queue is not empty:
• Dequeue and run the oldest microtask.
2. If this is a good time to render:
a. Do some prep work.
b. Run requestAnimationFrame callbacks.
c. Render.
3. If the macrotask queue is empty, wait till a macrotask appears.
4. Go to step 1.

- sync tasks → All micro tasks → requestAnimationFrame → 1 macro


task
- NOTE: executing a program is considered a macrotask so after it
exits, the microtask queue gets processed before the macrotask
queue.

EX:

console.log(1)
setTimeout(() => {
queueMicrotask(() => {
console.log(2)

184
});
console.log(3)
});
Promise.resolve().then(() => console.log(4))
queueMicrotask(() => {
console.log(5)
queueMicrotask(() => {
console.log(6)
});
});
console.log(7)

Sync Tasks Macrotasks Queue Microtasks


Queue

Log - 1 Execute the script (context) Log - 4


Indicated by undefined

Log - 7 Timeout – Log - 3 when this is Log - 5


done, we add log - 2 to
microtask as its parent is a
Timer.

Log - 6

Log - 2

output:

1 7 4 5 6 undefined 3 2

- 1,7 are sync so get printed. The microtask queue by the main
execution context is checked. There are two types of micro tasks here
one is the promise callback and the other is task queue by
queueMicroTask, which further puts another task in micro task queue.
So first 4 is printed, then 5 and as there is still a task remaining in
microtask queue 6 is also printed. After this the main execution
ends and undefined is printed and the program returns. Now it’s
time to look for tasks in macrotask queue. Here the callback of
setTimeout will be invoked. 3 is printed. The microtask queue is
checked again and 2 is printed finally.

Advance Example (need to know Angular & RxJS):

185
import { of, merge, asapScheduler, asyncScheduler, animationFrameScheduler,
queueScheduler } from 'rxjs';
import { filter, startWith, observeOn } from 'rxjs/operators';

const delay = 0;
const async$ = of('async')
.pipe(observeOn(asyncScheduler, delay)); // macro queue

const asap$ = of('asap')


.pipe(observeOn(asapScheduler, delay)); // micro queue

const animationFrame$ = of('animationFrameScheduler')


.pipe(observeOn(animationFrameScheduler, delay)); // before browser repaints

const queue$ = of('queue')


.pipe(observeOn(queueScheduler, delay)); // sync

merge(async$, asap$, animationFrame$, queue$)


.pipe(filter(x => !!x))
.subscribe(console.log);

console.log('after subscription');

output:

queue
after subscription
asap
animationFrameScheduler
async

More about microtasks


Microtasks for use cases
Event Loop advanced topic.
Great Conference for Event Loop.

186
187
JavaScript Debugging
Code Debugging
▪ Programming code might contain syntax errors or logical errors.
Many of these errors are difficult to diagnose.
▪ Often, There are no error messages and you will get no indications
where to search for errors.
▪ Searching for (and fixing) errors in programming code is called code
debugging.

JavaScript Debuggers
1. The console.log() Method
o If your browser supports debugging, you can
use console.log() to display JavaScript values in the debugger
window.

2. Setting Breakpoints
o In the debugger window, you can set breakpoints in the
JavaScript code. At each breakpoint, JavaScript will stop
executing and let you examine JavaScript values.
o After that you can resume the execution of code (typically with
a play button).

3. The debugger Keyword


o The debugger keyword stops (pause) the execution of
JavaScript and calls (if available) the debugging function.
o This has the same function as setting a breakpoint in the
debugger.
o After that you can resume the execution of code (typically with
a play button).
o If no debugging is available, the debugger statement has no
effect.

188
JavaScript Style Guide & Coding Conventions
▪ Always use the same coding conventions for all your JavaScript
projects.

JavaScript Coding Conventions


▪ Coding conventions are style guidelines for programming. They
typically cover:
o Naming and declaration rules for variables and functions.
o Rules for the use of white space, indentation and comments.
o Programming practices and principles.
▪ Coding conventions secure quality:
o Improves code readability.
o Make code maintenance easier.
▪ Coding conventions can be documented rules for teams to follow or
just be your individual coding practice.

Variable Names
▪ use camelCase for identifier names (variables and functions).

Spaces Around Operators


▪ Always put spaces around operators ( = + - * / ) and after commas.

Code Indentation
▪ Always use 2 spaces for indentation of code blocks.

Statement Rules
▪ General rules for simple statements:
o Always end a simple statement with a semicolon.
▪ General rules for complex (compound) statements:
o Put the opening bracket at the end of the first line.
o Use one space before the opening bracket.
o Put the closing bracket on a new line, without leading spaces.
o Do not end a complex statement with a semicolon.
if (time < 20) {

189
greeting = "Good day";
} else {
greeting = "Good evening";
}

Object Rules
▪ General rules for object definitions:
o Place the opening bracket on the same line as the object name.
o Use colon plus one space between each property and its value.
o Use quotes around string values, not around numeric values.
o Do not add a comma after the last property-value pair.
o Place the closing bracket on a new line, without leading spaces.
o Always end an object definition with a semicolon.
var person = {
firstName: "John",
lastName: "Doe",
age: 50,
eyeColor: "blue"
};

o Short objects can be written compressed, on one line, using


spaces only between properties.

Line Length
▪ For readability, avoid lines longer than 80 characters. If a
JavaScript statement does not fit on one line, the best place to break
it, is after an operator or a comma.

Naming Conventions
▪ Always use the same naming convention for all your code. For
example:
o Variable and function names written as camelCase
o Global variables and Constants written in UPPERCASE.
▪ Hyphens in HTML and CSS:
▪ HTML5 attributes can start with data- (data-quantity, data-price).
▪ CSS uses hyphens in property-names (font-size).

190
▪ Hyphens can be mistaken as subtraction attempts.
Hyphens are not allowed in JavaScript names.

▪ Underscores:
▪ Many programmers prefer to use underscores (date_of_birth),
especially in SQL databases.

▪ PascalCase:
▪ often preferred by C programmers.

▪ camelCase:
▪ camelCase is used by JavaScript itself, by jQuery and other
JavaScript libraries.

NOTE: Do not start names with a $ sign. It will put you in conflict with
many JavaScript library names.

Accessing HTML Elements


▪ A consequence of using "untidy" HTML styles, might result in
JavaScript errors.

var obj = getElementById("Demo")


var obj = getElementById("demo") // different result

File Extensions
▪ HTML files should have a .html extension (not .htm).
▪ CSS files should have a .css extension.
▪ JavaScript files should have a .js extension.

Use Lower Case File Names


- Most web servers (Apache, Unix) are case sensitive about file
names.
london.jpg cannot be accessed as London.jpg.
- Other web servers (Microsoft, IIS) are not case sensitive:
london.jpg can be accessed as London.jpg or london.jpg.
- Always use lower case file names, to avoid errors when moving from
a case insensitive, to a case sensitive server.

191
192
JavaScript Best Practices
Avoid Global Variables
- Minimize the use of global variables. This includes all data types,
objects and functions.it can be overwritten by other scripts.

Always Declare Local Variables


- All variables used in a function should be declared as local variables.
- Local variables must be declared with the var keyword or
the let keyword, otherwise they will become global variables.

Declarations on Top
- It is a good coding practice to put all declarations at the top of each
script or function.
- This will:
• Give cleaner code. Where all local variables in one place.
• Make it easier to avoid unwanted global variables.
• Reduce unwanted re-declarations.

Initialize Variables
- It is a good coding practice to initialize variables when you declare
them.
- This will:
• Give cleaner code.
• Provide a single place to initialize variables.
• Avoid undefined values.

Never Declare Number, String or Boolean Objects


- Declaring these types as objects, slows down execution speed and
produces nasty side effects.

Don't Use new Object()


- Use {} instead of new Object()
- Use "" instead of new String()
- Use 0 instead of new Number()

193
- Use false instead of new Boolean()
- Use [] instead of new Array()
- Use /()/ instead of new RegExp()
- Use function (){} instead of new Function()

Beware of Automatic Type Conversions


- JavaScript is loosely typed. A variable can contain different data
types and a variable can change its data type.

Use === Comparison


- The === operator forces comparison of values and type.

Use Parameter Defaults → ES6


- If a function is called with a missing argument, the value of the
missing argument is set to undefined. It is a good habit to assign
default values to arguments.
- ECMAScript 2015 allows default parameters.

End Your Switches with Defaults


- Always end your switch statements with a default. Even if you think
there is no need for it.

Avoid Using eval()


- The eval() function is used to run text as code. In almost all cases, it
should not be necessary to use it. Because it allows arbitrary code to
be run, it also represents a security problem.

194
JavaScript Common Mistakes
Accidentally Using the Assignment Operator
- uses an assignment operator (=), instead of a comparison operator
(==) in an if statement.

if (x = 10) // return true

- An assignment always return the value of assignment.

Misunderstanding Floats
var x = 0.1;
var y = 0.2;
var z = x + y // the result in z will not be 0.3

- To solve the problem above, it helps to multiply and divide:

var z = (x * 10 + y * 10) / 10; // z will be 0.3

Breaking a JavaScript String → ES5


- breaking a statement in the middle of a string, You must use a
"backslash" if you must break a statement in a string.

var x = "Hello \
World!";

Misplacing Semicolon
if (x == 19);
{
// code block will be executed
}

Breaking a Return Statement


- It is a default JavaScript behavior to close a statement automatically
at the end of a line.

function myFunction(a) {
var power = 10
return a * power // so this will work as expected
}

195
- Never break a return statement.

return // will return undefined and next line not executed


a * power;

Accessing Arrays with Named Indexes


- Many programming languages support arrays with named indexes.
- Arrays with named indexes are called associative arrays (hashes).
- JavaScript does not support arrays with named
indexes, arrays use numbered indexes.
- In JavaScript, objects use named indexes.
- If you use a named index, when accessing an array, JavaScript will
redefine the array to a standard object.
- After the automatic redefinition, array methods and properties will
produce undefined or incorrect results.

var person = [];


person["firstName"] = "John";
person["lastName"] = "Doe";
person["age"] = 46;
var x = person.length; // person.length will return 0
var y = person[0]; // person[0] will return undefined

Ending Definitions with a Comma → ES5


- Trailing commas in object and array definition are legal in ECMAScript
5.
- Internet Explorer 8 will crash.
- JSON does not allow trailing commas.

Undefined is Not Null


- JavaScript objects, variables, properties and methods can
be undefined.
- In addition, empty JavaScript objects can have the value null.
- This can make it a little bit difficult to test if an object is empty.
- You can test if an object exists by testing if the type is undefined.

if (typeof myObj === "undefined")

196
- But you cannot test if an object is null, because this will throw an
error if the object is undefined.

if (myObj === null)

- To solve this problem, you must test if an object is not null and
not undefined. But this can still throw an error.

if (myObj !== null && typeof myObj !== "undefined")

- Because of this, you must test for not undefined before you can test
for not null.

if (typeof myObj !== "undefined" && myObj !== null)

Another way for objects


- !null = true, and !undefined = true, So you can use !myObj which
will indicate that myObj can be undefined or null, another (!) will
make the same conditions above.

if (!!myObj)

197
JavaScript Performance (speed up your code)
Reduce Activity in Loops
- Statements or assignments that can be placed outside the loop will
make the loop run faster.

var i;
var l = arr.length;
for (i = 0; i < l; i++) {

Reduce DOM Access


- Accessing the HTML DOM is very slow, compared to other JavaScript
statements.
- If you expect to access a DOM element several times, access it once
and use it as a local variable.
var obj;
obj = document.getElementById("demo");
obj.innerHTML = "Hello";

Reduce DOM Size


- Keep the number of elements in the HTML DOM small.
- This will always improve page loading, speed up rendering (page
display) and search the DOM will benefit from it too.

Avoid Unnecessary Variables


- Don't create new variables if you don't plan to save values.

var fullName = firstName + " " + lastName;


document.getElementById("demo").innerHTML = fullName;

change it to this:
document.getElementById("demo").innerHTML = firstName + " " + lastName;

Delay JavaScript Loading


- Putting your scripts at the bottom of the page body lets the browser
load the page first.
- While a script is downloading, the browser will not start any other
downloads. In addition all parsing and rendering activity might be
blocked.

198
- The HTTP specification defines that browsers should not download
more than two components in parallel.
- An alternative is to use defer="true" in the script tag. The defer
attribute specifies that the script should be executed after the page
has finished parsing, but it only works for external scripts.

199
JavaScript Forms
JavaScript Form Validation
- HTML form validation can be done by JavaScript.
- The (validation function) can be called when the form is submitted.

<form name="myForm" action="/action.php" onsubmit="return validateForm()"


method="post"></form>

Data Validation
- Data validation is the process of ensuring that user input is clean,
correct and useful.
- Validation can be defined by many different methods and deployed in
many different ways.
1. Server side validation is performed by a web server, after
input has been sent to the server.
2. Client side validation is performed by a web browser, before
input is sent to a web server.

HTML Constraint Validation


o HTML5 introduced a new HTML validation concept called constraint
validation.
o HTML constraint validation is based on (should use them all):
1. Constraint Validation HTML Input Attributes

Attribute Description

disabled the input element should be disabled

max the maximum value of an input element

min the minimum value of an input element

pattern the value pattern of an input element

required the input field requires an element

type the type of an input element

For a full list, go to HTML Input Attributes.

200
2. Constraint Validation CSS Pseudo Selectors

Selector Description

:disabled Selects input elements with the "disabled" attribute


specified

:invalid Selects input elements with invalid values

:optional Selects input elements with no "required" attribute


specified

:required Selects input elements with the "required" attribute


specified

:valid Selects input elements with valid values

For a full list, go to CSS Pseudo Classes.

3. Constraint Validation DOM Methods

Property Description

checkValidity() Returns true if an input element contains


valid data.

setCustomValidity() Sets the validationMessage property of an


input element.

function myFunction() {
var inpObj = document.getElementById("id1");
if (!inpObj.checkValidity()) {
document.getElementById("demo").innerHTML = inpObj.validationMessage;
}
}

4. Constraint Validation DOM Properties

Property Description

201
validity Contains boolean properties related to the
validity of an input element.

validationMessage Contains the message a browser will display


when the validity is false.

willValidate Indicates if an input element will be


validated.

a. Validity Properties

Property Description

customError Set to true, if a custom validity message


is set.

patternMismatch Set to true, if an element's value does not


match its pattern attribute.

rangeOverflow Set to true, if an element's value is


greater than its max attribute.

rangeUnderflow Set to true, if an element's value is less


than its min attribute.

stepMismatch Set to true, if an element's value is


invalid per its step attribute.

tooLong Set to true, if an element's value exceeds


its maxLength attribute.

typeMismatch Set to true, if an element's value is


invalid per its type attribute.

valueMissing Set to true, if an element (with a required


attribute) has no value.

valid Set to true, if an element's value is valid.

202
HTML DOM
- With the HTML DOM, JavaScript can access and change all the
elements of an HTML document.
- When a web page is loaded, the browser creates
a Document Object Model of the page.
- The HTML DOM model is constructed as a tree of Objects.

- With the object model, JavaScript gets all the power it needs to
create dynamic HTML:
• JS can change all the HTML elements in the page.
• JS can change all the HTML attributes in the page.
• JS can change all the CSS styles in the page.
• JS can remove existing HTML elements and attributes.
• JS can add new HTML elements and attributes.
• JS can react to all existing HTML events in the page.
• JS can create new HTML events in the page.

What is the DOM?


- The DOM is a W3C (World Wide Web Consortium) standard. It defines
a standard for accessing documents.
- The W3C DOM standard is separated into 3 different parts:

• Core DOM - standard model for all document types.


• XML DOM - standard model for XML documents.
• HTML DOM - standard model for HTML documents.

203
What is the HTML DOM?
- The HTML DOM is a standard object model and programming
interface for HTML. It defines:

1. The HTML elements as objects.


2. The properties of all HTML elements.
3. The methods to access all HTML elements.
4. The events for all HTML elements.

- In other words: The HTML DOM is a standard for how to get,


change, add or delete HTML elements.

204
HTML DOM Methods
The DOM Programming Interface
- The HTML DOM can be accessed with JavaScript.
- In the DOM, all HTML elements are defined as objects.
- The programming interface is the properties and methods of
each object.
- A property is a value that you can get or set (like changing the
content of an HTML element).
- A method is an action you can do (like add or deleting an HTML
element).

<html>
<body>
<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = "Hello World!";
</script>
</body>
</html>

- In the example above, getElementById is a method,


while innerHTML is a property.

205
HTML DOM Document
The HTML DOM Document Object
- The HTML DOM document object is the owner of all other objects in
your web page.
- If you want to access any element in an HTML page, you always start
with accessing the document object.

Finding HTML Objects


- The first HTML DOM Level 1 (1998), defined 11 HTML objects, object
collections and properties. These are still valid in HTML5. Later, in
HTML DOM Level 3, more objects, collections and properties were
added.

Property Description DOM

document.anchors Returns all <a> elements that have a 1


name attribute

document.baseURI Returns the absolute base URI of the 3


document

document.body Returns the <body> element 1

document.cookie Returns the document's cookie 1

document.doctype Returns the document's doctype 3

document.documentElement Returns the <html> element 3

document.documentMode Returns the mode used by the browser 3

document.documentURI Returns the URI of the document 3

document.domain Returns the domain name of the 1


document server

document.domConfig Obsolete. Returns the DOM configuration 3

document.embeds Returns all <embed> elements 3

document.forms Returns all <form> elements 1

document.head Returns the <head> element 3

document.images Returns all <img> elements 1

206
document.implementation Returns the DOM implementation 3

document.inputEncoding Returns the document's encoding 3


(character set)

document.lastModified Returns the date and time the document 3


was updated

document.links Returns all <area> and <a> elements 1


that have a href attribute

document.readyState Returns the (loading) status of the 3


document

document.referrer Returns the URI of the referrer (the linking 1


document)

document.scripts Returns all <script> elements 3

document.strictErrorChecking Returns if error checking is enforced 3

document.title Returns the <title> element 1

document.URL Returns the complete URL of the 1


document

207
HTML DOM Collections
The HTMLCollection Object
- As example, getElementsByTagName() method returns
an HTMLCollection object.
- An HTMLCollection object is an array-like list (collection) of HTML
elements.
- The elements in the collection can be accessed by an index number.
EX: The following code selects all <p> elements in a document:

var x = document.getElementsByTagName("p");

EX: To access the second <p> element you can write:

y = x[1];

- Note: The index starts at 0.

HTML HTMLCollection Length


- The length property defines the number of elements in
an HTMLCollection.
EX: Create a collection of all <p> elements. Then Display the length of
the collection.

var myCollection = document.getElementsByTagName("p");


document.getElementById("demo").innerHTML = myCollection.length;

- The length property is useful when you want to loop through the
elements in a collection.

var myCollection = document.getElementsByTagName("p");


var i;
for (i = 0; i < myCollection.length; i++) {
myCollection[i].style.backgroundColor = "red";
}

Methods
1. HTMLCollection.item(index)
- Returns the specific node at the given index into the list.
Returns null if the index is out of range.
- An alternative to accessing collection[i].

208
2. HTMLCollection.namedItem(ID)
- Returns the specific node whose ID or as a fallback name matches
the string specified by name. Matching by name is only done as a last
resort, only in HTML and only if the referenced element supports
the name attribute. Returns null if no node exists by the given
name.
- An alternative to accessing collection[name].

• An HTMLCollection is NOT an array!

An HTMLCollection may look like an array, but it is not. You can loop
through the list and refer to the elements with a number (just like an
array).

However, you can’t use array methods like valueOf(), pop(), push(), or
join() on an HTMLCollection.

209
HTML DOM Navigation
- With the HTML DOM, you can navigate the node tree using node
relationships.

DOM Nodes
- According to the W3C HTML DOM standard, everything in an HTML
document is a node:

o The entire document is a document node.


o Every HTML element is an element node.
o The text inside HTML elements are text nodes.
o All comments are comment nodes.

- With the HTML DOM, all nodes in the node tree can be accessed by
JavaScript.
- New nodes can be created and all nodes can be modified or deleted.

Node Relationships
- The nodes in the node tree have a hierarchical relationship to each
other.
- The terms parent, child and sibling (‫ )إخوان‬are used to describe the
relationships:

o In a node tree, the top node is called the root (or root node).
o Every node has exactly one parent, except the root (which has
no parent).
o A node can have a number of children.
o Siblings (brothers or sisters) are nodes with the same parent.

<html>

<head>
<title>DOM Tutorial</title>
</head>

<body>
<h1>DOM Lesson one</h1>
<p>Hello world!</p>
</body>

210
</html>

- From the HTML above you can read:


o <html> is the root node.
o <html> has no parents.
o <html> is the parent of <head> and <body>.
o <head> is the first child of <html>.
o <body> is the last child of <html>.

- and:
o <head> has one child: <title>.
o <title> has one child (a text node): "DOM Tutorial".
o <body> has two children: <h1> and <p>.
o <h1> has one child: "DOM Lesson one".
o <p> has one child: "Hello world!".
o <h1> and <p> are siblings.

Navigating Between Nodes


- You can use the following node properties to navigate between nodes
with JavaScript:
o parentNode
o childNodes[nodenumber]
o firstChild
o lastChild
o nextSibling
o previousSibling

211
Child Nodes and Node Values
- A common error in DOM processing is to expect an element node to
contain text.

<title id="demo">DOM Tutorial</title>

- The element node <title> (in the example above) does not contain
text.
- It contains a text node with the value "DOM Tutorial".
- The value of the text node can be accessed by the
node's innerHTML property:

var myTitle = document.getElementById("demo").innerHTML;

- Accessing the innerHTML property is the same as accessing


the nodeValue of the first child:

var myTitle = document.getElementById("demo").firstChild.nodeValue;

- Accessing the first child can also be done like this:

var myTitle = document.getElementById("demo").childNodes[0].nodeValue;

InnerHTML
- In this tutorial we use the innerHTML property to retrieve the content
of an HTML element.
- However, learning the other methods above is useful for
understanding the tree structure and the navigation of the DOM.

DOM Root Nodes


- There are two special properties that allow access to the full
document:
• document.body - The body of the document.
• document.documentElement - The full document.

EX
<html>
<body>

<p>Hello World!</p>

212
<div>
<p>The DOM is very useful!</p>
<p>This example demonstrates the <b>document.body</b> property.</p>
</div>

<script>
alert(document.body.innerHTML);
alert(document.documentElement.innerHTML);
</script>

</body>
</html>

The nodeName Property


- The nodeName property specifies the name of a node.
o It is read-only.
o nodeName of an element node is the same as the tag name.
o nodeName of an attribute node is the attribute name.
o nodeName of a text node is always #text.
o nodeName of the document node is always #document.

<h1 id="id01">My First Page</h1>


<p id="id02"></p>

<script>
document.getElementById("id02").innerHTML =
document.getElementById("id01").nodeName;
</script>

- Note: nodeName always contains the uppercase tag name of an HTML


element.

The nodeValue Property


- The nodeValue property specifies the value of a node.
o nodeValue for element nodes is null.
o nodeValue for text nodes is the text itself.
o nodeValue for attribute nodes is the attribute value.

213
The nodeType Property
- The nodeType property is read only. It returns the type of a node.

<h1 id="id01">My First Page</h1>


<p id="id02"></p>

<script>
document.getElementById("id02").innerHTML =
document.getElementById("id01").nodeType;
</script>

- Type 2 is deprecated in the HTML DOM (but works). It is not


deprecated in the XML DOM.
- The most important nodeType properties are:

Node Type Example

ELEMENT_NODE 1 <h1
class="heading">W3Schools</h1>

ATTRIBUTE_NODE 2 class = "heading" (deprecated)

TEXT_NODE 3 W3Schools

COMMENT_NODE 8 <!-- This is a comment -->

DOCUMENT_NODE 9 The HTML document itself (the


parent of <html>)

DOCUMENT_TYPE_NODE 10 <!Doctype html>

214
HTML DOM Node Lists
The HTML DOM NodeList Object
- A NodeList object is a list (collection) of nodes extracted from a
document.
- childNodes return a Live NodeList object for the property .
- querySelectorAll() return a Static NodeList object for the method.
- Some (older) browsers return a NodeList object instead of an
HTMLCollection for methods like getElementsByClassName().
EX: The following code selects all <p> nodes in a document.

var myNodeList = document.querySelectorAll("p");

- The elements in the NodeList can be accessed by an index number.


EX: To access the second <p> node you can write:

y = myNodeList[1];

- Note: The index starts at 0.

HTML DOM Node List Length


- The length property defines the number of nodes in a node list.
EX: Create a list of all <p> elements. Then display the length of the
list.

myNodelist = document.querySelectorAll("p");
document.getElementById("demo").innerHTML = myNodelist.length;

- The length property is useful when you want to loop through the
nodes in a node list.
EX: Change the background color of all <p> elements in a node list
var myNodelist = document.querySelectorAll("p");
var i;
for (i = 0; i < myNodelist.length; i++) {
myNodelist[i].style.backgroundColor = "red";
}

HTML DOM Node List Methods


• NodeList.item()
- Returns an item in the list by its index or null if the index is
out-of-bounds.

215
- An alternative to accessing nodeList[i].

• NodeList.entries()
- Returns an iterator, allowing code to go through all key/value
pairs contained in the collection. (In this case, the keys are
numbers starting from 0 and the values are nodes)

• NodeList.forEach()
- Executes a provided function once per NodeList element,
passing the element as an argument to the function.

• NodeList.keys()
- Returns an iterator, allowing code to go through all the keys of
the key/value pairs contained in the collection. (In this case,
the keys are numbers starting from 0)

• NodeList.values()
- Returns an iterator allowing code to go through all values
(nodes) of the key/value pairs contained in the collection.

• Use for..of for looping purpose.

The Difference Between an HTMLCollection and a NodeList?


- An HTMLCollection is a collection of HTML elements.
- A NodeList is a collection of document nodes.
- A NodeList and an HTML collection is very much the same thing.
- Both an HTMLCollection object and a NodeList object is an array-like
list (collection) of objects.
- Both have a length property defining the number of items in the list
(collection).
- Both provide an index (0, 1, 2 ...) to access each item like an array.
- HTMLCollection items can be accessed by their name, id or index
number.
- NodeList items can only be accessed by their index number.
- Only the NodeList object can contain attribute nodes and text
nodes.

• A node list is NOT an array!

216
A node list may look like an array, but it is not. You can loop through the
node list and refer to its nodes like an array.

However, you can’t use Array Methods, like valueOf(), push(), pop(), or
join() on a node list.

217
HTML DOM Elements (Nodes)
- Adding and Removing Nodes (HTML Elements).
Creating New HTML Elements (Nodes)
- To add a new element to the HTML DOM, you must create the
element (element node) first and then append it to an existing
element.

<div id="div1">
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>

<script>
var para = document.createElement("p");
var node = document.createTextNode("This is new.");
para.appendChild(node);

var element = document.getElementById("div1");


element.appendChild(para);
</script>

- You can use innerHTML or innerText to add text of a new element


without using createTextNode.

o Example Explained
This code creates a new <p> element.

var para = document.createElement("p");

To add text to the <p> element, you must create a text node
first. This code creates a text node.

var node = document.createTextNode("This is a new paragraph.");

- Then you must append the text node to the <p> element.

para.appendChild(node);

- Finally you must append the new element to an existing


element. This code finds an existing element.

var element = document.getElementById("div1");

218
- This code appends the new element to the existing element.

element.appendChild(para);

Creating new HTML Elements - insertBefore()


- The appendChild(newNode) method in the previous example,
appended the new element as the last child of the parent.
- If you don't want that you can use the insertBefore(newNode,
existingNode) method.

<div id="div1">
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>

<script>
var para = document.createElement("p");
var node = document.createTextNode("This is new.");
para.appendChild(node);

var element = document.getElementById("div1");


var child = document.getElementById("p1");
element.insertBefore(para, child);
</script>

Removing Existing HTML Elements


- To remove an HTML element, use the remove() method.

<div>
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>

<script>

219
var elmnt = document.getElementById("p1");
elmnt.remove();
</script>

o Example Explained
- The HTML document contains a <div> element with two
child nodes (two <p> elements).

<div>
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>

- Find the element you want to remove.

var elmnt = document.getElementById("p1");

- Then execute the remove() method on that element.

elmnt.remove();

- The remove() method does not work in older browsers, see the
example below on how to use removeChild() instead.

Removing a Child Node


- For browsers that does not support the remove(child) method, you
have to find the parent node to remove an element.

<div id="div1">
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>

<script>
var parent = document.getElementById("div1");
var child = document.getElementById("p1");
parent.removeChild(child);
</script>

o Example Explained

220
- This HTML document contains a <div> element with two
child nodes (two <p> elements).

<div id="div1">
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>

- Find the element with id="div1".

var parent = document.getElementById("div1");

- Find the <p> element with id="p1".

var child = document.getElementById("p1");

- Remove the child from the parent:

parent.removeChild(child);

- Here is a common workaround: Find the child you want


to remove and use its parentNode property to find the
parent.

var child = document.getElementById("p1");


child.parentNode.removeChild(child);

Replacing HTML Elements


- To replace an element to the HTML DOM, use
the replaceChild(newNode, oldNode) method.

<div id="div1">
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>

<script>
var para = document.createElement("p");
var node = document.createTextNode("This is new.");
para.appendChild(node);

var parent = document.getElementById("div1");


var child = document.getElementById("p1");
parent.replaceChild(para, child);

221
</script>

222
TML DOM Elements
Finding HTML Elements
- Often, with JavaScript, you want to manipulate HTML elements. To do
so, you have to find the elements first. There are several ways to do
this:

1. Finding HTML Element by Id


- getElementById() method is the easiest way to find an HTML element
in the DOM using the element id.

var myElement = document.getElementById("intro");

- If the element is found, the method will return the element as an


object. If the element is not found, It will return null.
- The ID is case-sensitive string.
- It is only available as a method of the global document object,
and not available as a method on all element objects in the DOM.

2. Finding HTML Elements by Tag Name


- getElementsByTagName() method finds element by its tag name.
- It returns a live HTMLCollection of elements with the given tag
name. The returned list is live, which means it updates itself with the
DOM tree automatically. Therefore, there is no need to
call Element.getElementsByTagName() with the same element and
arguments repeatedly if the DOM changes in between calls.
- If no elements found, empty HTMLCollection[] returned.
- You may also call it on any element object.
EX: finds all <p> elements.

var x = document.getElementsByTagName("p");

EX: finds the element with id="main", and then finds all <p> elements
inside "main".

var x = document.getElementById("main");
var y = x.getElementsByTagName("p");

3. Finding HTML Elements by Class Name


- getElementsByClassName(‘className1 className2 ...’) method
finds all HTML elements with the same class name.

223
- It returns live HTMLCollection of found elements. If no elements
found, empty HTMLCollection returned.
- You may also call it on any element object.
- You can look for multiple class names, separated by whitespace.
EX: returns a list of all elements with class="intro".

var x = document.getElementsByClassName("intro");

- Finding elements by class name does not work in Internet Explorer 8


and earlier versions.

4. Finding HTML Elements by CSS Selectors


- querySelectorAll(“selector1, selector2”) method finds all HTML
elements that match a specified CSS selector (id, class names, types,
attributes, values of attributes ... etc.).
- It returns a static (not live) NodeList representing a list of the
elements that match the specified selectors.
- You can look for different selectors by separate them with comma.
You can look for multiple selectors in selector1, separated by
whitespace.
- You may also call it on any element object.
- Finding elements should be described very well, something like the
example below can return any element with just one class name.
EX:

var inner = select.querySelectorAll('.outer .inner');

EX: find an input by a property inside a div with class names.

var el = document.querySelector("div.user-panel.main input[name='login']");

EX: returns a list of all <p> elements with class="intro".

var x = document.querySelectorAll("p.intro");

- The querySelectorAll() method does not work in Internet Explorer 8


and earlier versions.

5. Finding HTML Element by CSS Selector


- querySelector(“selector1, selector2”) method finds the first
HTML element that match a specified CSS selector (id, class names,
types, attributes, values of attributes ... etc.).
- It returns an element object that match the specified selectors, or
null if there is no match.

224
- You can look for different selectors by separate them with comma.
You can look for multiple selectors in selector1, separated by
whitespace.
- For special characters, you must escape it twice (once for the
JavaScript string and another time for querySelector())
EX: Match a div with id=‘foo:bar’

document.querySelector('#foo\\:bar');

EX: returns an element with class="intro for".

var x = document.querySelector(".intro .for");

6. Finding HTML Elements by HTML Object Collections


- This example finds the form element with id="frm1", in the forms
collection and displays all element values.
- You can just look for any collection on ID property.

var x = document.forms["frm1"];
var text = "";
var i;
for (i = 0; i < x.length; i++) {
text += x.elements[i].value + "<br>";
}
document.getElementById("demo").innerHTML = text;

225
HTML DOM - Changing HTML
Changing the HTML Output Stream
- The HTML DOM allows JavaScript to change the content of HTML
elements.
- In JavaScript, document.write() can be used to write directly to
the HTML output stream.
<!DOCTYPE html>
<html>
<body>

<script>
document.write(Date());
</script>

</body>
</html>

- Never use document.write() after the document is loaded. It will


overwrite the document.

Changing HTML Content


- The easiest way to modify the content of an HTML element is by
using the innerHTML property.
- To change the content of an HTML element, use this syntax.

document.getElementById(id).innerHTML = new HTML

EX: This example changes the content of a <p> element.

<html>
<body>

<p id="p1">Hello World!</p>

<script>
document.getElementById("p1").innerHTML = "New text!";
</script>

226
</body>
</html>

Changing the Value of an Attribute


- To change the value of an HTML attribute, use this syntax.

document.getElementById(id).attribute = new value

EX: This example changes the value of the src attribute of


an <img> element.

<!DOCTYPE html>
<html>
<body>

<img id="myImage" src="smiley.gif">

<script>
document.getElementById("myImage").src = "landscape.jpg";
</script>

</body>
</html>

Changing HTML Style – Changing CSS


- To change the style of an HTML element, use this syntax.
document.getElementById(id).style.property = new style

EX: The following example changes the style of a <p> element.


<html>
<body>

<p id="p2">Hello World!</p>

<script>
document.getElementById("p2").style.color = "blue";

227
</script>

<p>The paragraph above was changed by a script.</p>

</body>
</html>

- HTML DOM Style Object Reference.

228
HTML DOM Animation
A Basic Web Page
- To demonstrate how to create HTML animations with JavaScript,
we will use a simple web page.
<!DOCTYPE html>
<html>
<body>

<h1>My First JavaScript Animation</h1>

<div id="animation">My animation will go here</div>

</body>
</html>

Create an Animation Container


- All animations should be relative to a container element.
<div id ="container">
<div id ="animate">My animation will go here</div>
</div>

Style the Elements


- The container element should be created with style = "position:
relative".
- The animation element should be created with style = "position:
absolute".

#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;

229
height: 50px;
position: absolute;
background: red;
}

Animation Code
- JavaScript animations are done by programming gradual changes in
an element's style.
- The changes are called by a timer. When the timer interval is small,
the animation looks continuous.

var id = setInterval(frame, 5);

function frame() {
if (/* test for finished */) {
clearInterval(id);
} else {
/* code to change the element style */
}
}

Create the Animation Using JavaScript


function myMove() {
var elem = document.getElementById("animate");
var pos = 0;
var id = setInterval(frame, 5);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}

230
}

231
HTML DOM Events
- HTML DOM allows JavaScript to react to HTML events.
- HTML events are "things" that happen to HTML elements.
- An HTML event can be something the browser does or something a
user does.
- JavaScript lets you execute code when events are detected.
- HTML allows event handler attributes, with JavaScript code, to be
added to HTML elements.

Reacting to Events
- A JavaScript can be executed when an event occurs, like when a user
clicks on an HTML element.
- To execute code when a user clicks on an element, add JavaScript
code to an HTML event attribute.
onclick=JavaScript
Examples of HTML events:
• When a user clicks the mouse.
• When a web page has loaded.
• When an image has been loaded.
• When the mouse moves over an element.
• When an input field is changed.
• When an HTML form is submitted.
• When a user strokes a key.

EX: the content of the <h1> element is changed when a user clicks on
it.
<!DOCTYPE html>
<html>
<body>

<h1 onclick="this.innerHTML = 'Ooops!'">Click on this text!</h1>

</body>
</html>

EX: a function is called from the event handler:


<!DOCTYPE html>

232
<html>
<body>

<h1 onclick="changeText(this)">Click on this text!</h1>

<script>
function changeText(id) {
id.innerHTML = "Ooops!";
}
</script>

</body>
</html>

HTML Event Attributes


- To assign events to HTML elements you can use event attributes.

<button onclick="displayDate()">Try it</button>

- In the example above, a function named displayDate will be executed


when the button is clicked.

Assign Events Using the HTML DOM


- The HTML DOM allows you to assign events to HTML elements using
JavaScript.

<script>
document.getElementById("myBtn").onclick = displayDate;
</script>

- In the example above, a function named displayDate is assigned to


an HTML element with the id="myBtn". The function will be executed
when the button is clicked.

The onload and onunload Events


- The onload and onunload events are triggered when the user enters
or leaves the page.

233
- The onload event can be used to check the visitor's browser type and
browser version and load the proper version of the web page based
on the information.
- The onload and onunload events can be used to deal with cookies.

<body onload="checkCookies()"></body>

The onchange Event


- The onchange event is often used in combination with validation of
input fields.
- Below is an example of how to use the onchange.
The upperCase() function will be called when a user changes the
content of an input field.

<input type="text" id="fname" onchange="upperCase()">

The onmouseover and onmouseout Events


- The onmouseover and onmouseout events can be used to trigger a
function when the user mouses over or out of an HTML element.

<!DOCTYPE html>
<html>
<body>
<div onmouseover="mOver(this)" onmouseout="mOut(this)"
style="background-color:#D94A38;width:120px;height:20px;padding:40px;">
Mouse Over Me</div>

<script>
function mOver(obj) {
obj.innerHTML = "Thank You"
}

function mOut(obj) {
obj.innerHTML = "Mouse Over Me"
}
</script>

</body>

234
</html>

The onmousedown, onmouseup and onclick Events


- The onmousedown, onmouseup and onclick events are all parts of a
mouse-click. First when a mouse-button is clicked, the onmousedown
event is triggered, then when the mouse-button is released, the
onmouseup event is triggered, finally when the mouse-click is
completed, the onclick event is triggered.

<!DOCTYPE html>
<html>
<body>

<div onmousedown="mDown(this)" onmouseup="mUp(this)"


style="background-color:#D94A38;width:90px;height:20px;padding:40px;">
Click Me</div>

<script>
function mDown(obj) {
obj.style.backgroundColor = "#1ec5e5";
obj.innerHTML = "Release Me";
}

function mUp(obj) {
obj.style.backgroundColor="#D94A38";
obj.innerHTML="Thank You";
}
</script>

</body>
</html>

More Examples
- onmousedown and onmouseup
Change an image when a user holds down the mouse button.
- onload
Display an alert box when the page has finished loading.

235
- onfocus
Change the background-color of an input field when it gets focus.
- Mouse Events
Change the color of an element when the cursor moves over it.

HTML DOM Event Object Reference.

236
HTML DOM EventListener
The addEventListener() method
document.getElementById("myBtn").addEventListener("click", displayDate);

- The addEventListener() method attaches an event handler to the


specified element without overwriting existing event handlers.
- You can add many event handlers to one element. You can add many
event handlers of the same type to one element, i.e two "click"
events.
- You can add event listeners to any DOM object not only HTML
elements. i.e. the window object.
- The addEventListener() method makes it easier to control how the
event reacts to bubbling.
- When using the addEventListener() method, the JavaScript is
separated from the HTML markup for better readability and allows
you to add event listeners even when you do not control the HTML
markup.
- You can easily remove an event listener by using
the removeEventListener() method.

Syntax
element.addEventListener(event, function, useCapture);
- The first parameter is the type of the event (like "click" or
"mousedown" or any other HTML DOM Event)
- The second parameter is the function we want to call when the event
occurs.
- The third parameter is a boolean value specifying whether to use
event bubbling or event capturing. This parameter is optional.

- Note that you don't use the "on" prefix for the event; use "click"
instead of "onclick".

Add an Event Handler to an Element


element.addEventListener("click", function(){ alert("Hello World!"); });

- You can also refer to an external "named" function.

element.addEventListener("click", myFunction);

function myFunction() {

237
alert ("Hello World!");
}

Add Many Event Handlers to the Same Element


- The addEventListener() method allows you to add many events to
the same element without overwriting existing events:

element.addEventListener("click", myFunction);
element.addEventListener("click", mySecondFunction);

- You can add events of different types to the same element:


element.addEventListener("mouseover", myFunction);
element.addEventListener("click", mySecondFunction);
element.addEventListener("mouseout", myThirdFunction);

Add an Event Handler to the window Object


- The addEventListener() method allows you to add event listeners on
any HTML DOM object such as HTML elements, the HTML document,
the window object or other objects that support events, like
the xmlHttpRequest object.

window.addEventListener("resize", function(){
document.getElementById("demo").innerHTML = sometext;
});

Passing Parameters
- When passing parameter values, use an "anonymous function" that
calls the specified function with the parameters.

var p1 = 5;
var p2 = 7;

document.getElementById("myBtn").addEventListener("click", function() {
myFunction(p1, p2);
});

Event Bubbling or Event Capturing?


- There are two ways of event propagation in the HTML DOM, bubbling
and capturing.

238
- Event propagation is a way of defining the element order when an
event occurs. If you have a <p> element inside a <div> element and
the user clicks on the <p> element, which element's "click" event
should be handled first?
- In bubbling the inner most element's event is handled first and
then the outer: the <p> element's click event is handled first then the
<div> element's click event.
- In capturing the outer most element's event is handled first and
then the inner: the <div> element's click event will be handled first
then the <p> element's click event.
- With the addEventListener() method you can specify the propagation
type by using the "useCapture" parameter.
addEventListener(event, function, useCapture);
- The default value is false, which will use the bubbling propagation,
when the value is set to true, the event uses the capturing
propagation.

document.getElementById("myP").addEventListener("click", myFunction, true);


document.getElementById("myDiv").addEventListener("click", myFunction, true);

The removeEventListener() method


- The removeEventListener() method removes event handlers that
have been attached with the addEventListener() method.

element.removeEventListener("mousemove", myFunction);

Browser Support
- Note: The addEventListener() and removeEventListener() methods
are not supported in IE 8 and earlier versions. However, for these
specific browser versions, you can use the attachEvent() method to
attach an event handlers to the element, and
the detachEvent() method to remove it:
element.attachEvent(event, function);
element.detachEvent(event, function);

var x = document.getElementById("myBtn");
if (x.addEventListener) { // For all major browsers, except IE 8 and earlier
x.addEventListener("click", myFunction);
} else if (x.attachEvent) { // For IE 8 and earlier versions
x.attachEvent("onclick", myFunction);
}

239
preventDefault Event Method
- The preventDefault() method cancels the event if it is cancelable,
meaning that the default action that belongs to the event will not
occur.
- For example, this can be useful when:
• Clicking on a "Submit" button, prevent it from submitting a
form.
• Clicking on a link, prevent the link from following the URL.

- Note: Not all events are cancelable. Use the cancelable property to
find out if an event is cancelable.
- Note: The preventDefault() method doesn’t prevent further
propagation of an event through the DOM. Use the stopPropagation()
method to handle this.

StopPropagation Event Method


- The event.stopPropagation() method prevents propagation of the
same event from being called.
- Propagation means bubbling up to parent elements or capturing down
to child elements.

stopImmediatePropagation Event Method


- event.stopImmediatePropagation(), when clicking on a button,
execute the first event handler and stop the rest of the event
handlers from being executed:

var x = document.getElementById("myBtn");
x.addEventListener("click", myFunction);
x.addEventListener("click", someOtherFunction);

function myFunction(event) {
alert ("Hello World!");
event.stopImmediatePropagation();
}

// This function will not be executed


function someOtherFunction() {

240
alert ("I will not get to say Hello World");
}

HTML DOM Event Object Reference.

241
Browser BOM
The Browser Object Model (BOM)
- There are no official standards for the Browser Object Model (BOM).

The Window Object


- The window object is supported by all browsers. It represents the
browser's window.
- All global JavaScript objects, functions and variables automatically
become members of the window object.
- Even the document object (of the HTML DOM) is a property of the
window object:

window.document.getElementById("header");

- is the same as:

document.getElementById("header");

Window Size
- Two properties can be used to determine the size of the browser
window. Both properties return the sizes in pixels:
o window.innerHeight - the inner height of the browser window.
o window.innerWidth - the inner width of the browser window.
- The browser window (the browser viewport) is NOT including toolbars
and scrollbars.
- For Internet Explorer 8, 7, 6, 5:
o document.documentElement.clientHeight
o document.documentElement.clientWidth or
o document.body.clientHeight
o document.body.clientWidth
EX: A practical JavaScript solution (covering all browsers, do for the
height in the same way):

var w = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;

Other Window Methods

242
Window Screen
- It contains information about the user's screen.

Window Screen Properties


- The window.screen object can be written without the window prefix.
- Properties:
o screen.width returns the width of the visitor's screen in pixels.
o screen.height returns the height of the visitor's screen in pixels.
o screen.availWidth returns the width of the visitor's screen, in
pixels, minus interface features like the Windows Taskbar.
o screen.availHeight returns the height of the visitor's screen, in
pixels, minus interface features like the Windows Taskbar.
o screen.colorDepth returns the number of bits used to display one
color.
All modern computers use 24 bit or 32 bit hardware for color
resolution:
• 24 bits = 16,777,216 different "True Colors".
• 32 bits = 4,294,967,296 different "Deep Colors".
• Older computers used 16 bits = 65,536 different "High
Colors" resolution.
• Very old computers and old cell phones used 8 bits = 256
different "VGA colors".
o screen.pixelDepth returns the pixel depth of the screen. For
modern computers, Color Depth and Pixel Depth are equal.

243
Window Location
- The window.location object can be used to get the current page
address (URL) and to redirect the browser to a new page.

Window Location Properties & Methods


- The window.location object can be written without the window
prefix.
- Properties:
o The location.hash property Sets “don’t include the hash sign” or
returns the anchor part of a URL including the hash sign (#).
o The location.href property Sets or returns the URL of the
current page.
o The location.host property Sets or returns the name of the
internet host and port number.
o The location.hostname property Sets or returns the name of the
internet host.
o The location.pathname property Sets or returns the pathname of
the current page.
o The location.protocol property Sets or returns the web protocol
of the page.
o The location.port property Sets or returns the number of the
internet host port.
Most browsers will not display default port numbers (80 for http
and 443 for https)

o The location.search property Sets or returns the querystring part


of a URL, including the question mark (?).
The querystring part is the part of the URL after the question mark
(?).
o The location.assign(“URL”) method loads a new document.

244
Window History
- The window.history object contains the browsers history. It can be
written without the window prefix.
- To protect the privacy of the users, there are limitations to how
JavaScript can access this object.

Window History Methods


o The history.back() method loads the previous URL in the history
list.
o The history.forward() method loads the next URL in the history
list.

245
Window Navigator
- The window.navigator object contains information about the
visitor's browser. It can be written without the window prefix.

Window Navigator Properties and Methods


o The navigator.cookieEnabled property returns true if cookies
are enabled, otherwise false.
o The navigator.appName property returns the application name
of the browser.
Strange enough, "Netscape" is the application name for both
IE11, Chrome, Firefox and Safari.
o The navigator.appCodeName property returns the application
code name of the browser.
"Mozilla" is the application code name for both Chrome, Firefox,
IE, Safari and Opera.
o The navigator.product property returns the product name of
the browser engine.
Do not rely on this. Most browsers returns "Gecko" as product
name !!
o The navigator.appVersion property returns version
information about the browser.
o The navigator.userAgent property returns the user-agent
header sent by the browser to the server.

o The navigator.platform property returns the browser platform


(operating system).

o The navigator.language property returns the browser's


language.

o The navigator.onLine property returns true if the browser is


online.

o The navigator.javaEnabled() method returns true if Java is


enabled.

Warning !!!
- The information from the navigator object can often be misleading,
and should not be used to detect browser versions because:

246
o Different browsers can use the same name.
o The navigator data can be changed by the browser owner.
o Some browsers misidentify themselves to bypass site tests.
o Browsers cannot report new operating systems, released later
than the browser.

247
Popup Boxes
- JavaScript has three kind of popup boxes: Alert box, Confirm box
and Prompt box.
- You can write all popup boxes without the window prefix.

1. Alert Box
- An alert box is often used if you want to make sure information
comes through to the user.
- When an alert box pops up, the user will have to click "OK" to
proceed.
- Syntax
window.alert("sometext");

2. Confirm Box
- A confirm box is often used if you want the user to verify or accept
something.
- When a confirm box pops up, the user will have to click either "OK" or
"Cancel" to proceed.
- If the user clicks "OK", the box returns true. If the user clicks
"Cancel", the box returns false.
- Syntax
window.confirm("sometext");

3. Prompt Box
- A prompt box is often used if you want the user to input a value
before entering a page.
- When a prompt box pops up, the user will have to click either "OK" or
"Cancel" to proceed after entering an input value.
- If the user clicks "OK" the box returns the input value. If the user
clicks "Cancel" the box returns null.
- Syntax
window.prompt("sometext","defaultText");

• Line Breaks
- To display line breaks inside a popup box, use a back-slash followed
by the character n.

248
249
Timing Events
- The window object allows execution of code at specified time intervals.
- These time intervals are called timing events.
- Timers are operated within a single thread and thus events might
queue up, waiting to be executed.

- The setTimeout() and setInterval() are both methods of the HTML


DOM Window object.

1. The setTimeout() Method


- Executes a function after waiting a specified number of milliseconds.
- setTimeout(function, milliseconds)

function to be executed.
milliseconds indicates the number of milliseconds before execution.

• How to Stop the Execution?


- The clearTimeout(timeoutVariable) method stops the execution of
the function specified in setTimeout().

myVar = setTimeout(function, milliseconds);


clearTimeout(myVar);

2. The setInterval() Method


- Repeats a given function at every given time-interval.
- setInterval(function, milliseconds)

function to be executed.
milliseconds indicates the length of the time-interval between each
execution.

• How to Stop the Execution?


- The clearInterval() method stops the executions of the function
specified in the setInterval() method.

myVar = setInterval(function, milliseconds);


clearInterval(myVar);

More Examples
- Another simple timing.
- A clock created with a timing event.

250
251
Cookies
What are Cookies?
- Cookies are data stored in small text files on user’s computer.
- When a web server has sent a web page to a browser, the connection
is shut down, and the server forgets everything about the user.
Cookies were invented to solve the problem "how to remember
information about the user".

o When a user visits a web page, his/her name can be stored in a


cookie.
o Next time the user visits the page, the cookie "remembers"
his/her name.

- Cookies are saved in name-value pairs like:


username = John Doe
- When a browser requests a web page from a server, cookies
belonging to the page are added to the request. This way the server
gets the necessary data to "remember" information about users.

Create a Cookie with JavaScript


- JavaScript can create, read and delete cookies with
the document.cookie property.
- With JavaScript, a cookie can be created like this.
document.cookie = "username=John Doe";

- You can also add an expiry date (in UTC time). By default, the cookie
is deleted when the browser is closed.

document.cookie = "username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC";

- With a path parameter, you can tell the browser what path the cookie
belongs to. By default, the cookie belongs to the current page.

document.cookie = "username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC;


path=/";

Read a Cookie with JavaScript


- With JavaScript, cookies can be read like this.

var x = document.cookie;

- document.cookie will return all cookies in one string much like:


cookie1=value; cookie2=value; cookie3=value;

252
Change a Cookie with JavaScript
- With JavaScript, you can change a cookie the same way as you
create it.

document.cookie = "username=John Smith; expires=Thu, 18 Dec 2013 12:00:00 UTC;


path=/";

- The old cookie is overwritten.

Delete a Cookie with JavaScript


- Deleting a cookie is very simple. You don't have to specify a cookie
value when you delete a cookie.
- Just set the expires parameter to a passed date.
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";

- You should define the cookie path to ensure that you delete the right
cookie. Some browsers will not let you delete a cookie if you don't
specify the path.

The Cookie String


- The document.cookie property looks like a normal text string, but it is
not. Even if you write a whole cookie string to document.cookie,
when you read it out again, you can only see the name-value pair of
it.
- If you set a new cookie, older cookies are not overwritten. The new
cookie is added to document.cookie, so if you read document.cookie
again you will get something like:
cookie1 = value; cookie2 = value;
- If you want to find the value of one specified cookie, you must write a
JavaScript function that searches for the cookie value in the cookie
string.

JavaScript Cookie Example


- In the example to follow, we will create a cookie that stores the name
of a visitor. The first time a visitor arrives to the web page, he/she
will be asked to fill in his/her name. The name is then stored in a
cookie. The next time the visitor arrives at the same page, he/she will
get a welcome message.
- For the example we will create 3 JavaScript functions:

253
1. A function to set a cookie value.
2. A function to get a cookie value.
3. A function to check a cookie value.

• A Function to Set a Cookie


- First, we create a function that stores the name of the visitor in a
cookie variable.

function setCookie(cname, cvalue, exdays) {


var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

Example explained:
The parameters of the function above are the name of the cookie
(cname), the value of the cookie (cvalue) and the number of days
until the cookie should expire (exdays). The function sets a cookie
by adding together the cookiename, the cookie value and the
expires string.

• A Function to Get a Cookie


- Then, we create a function that returns the value of a specified
cookie.

function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}

254
}
return "";
}

Function explained:
Take the cookiename as parameter (cname).
Create a variable (name) with the text to search for (cname + "=").
Decode the cookie string, to handle cookies with special
characters, e.g. '$'
Split document.cookie on semicolons into an array called ca (ca =
decodedCookie.split(';')).
Loop through the ca array (i = 0; i < ca.length; i++), and read
out each value c = ca[i]).
If the cookie is found (c.indexOf(name) == 0), return the value of
the cookie (c.substring(name.length, c.length).
If the cookie is not found, return "".

• A Function to Check a Cookie


- Last, we create the function that checks if a cookie is set.
- If the cookie is set it will display a greeting.
- If the cookie is not set, it will display a prompt box, asking for the
name of the user and stores the username cookie for 365 days by
calling the setCookie function.

function checkCookie() {
var username = getCookie("username");
if (username != "") {
alert("Welcome again " + username);
} else {
username = prompt("Please enter your name:", "");
if (username != "" && username != null) {
setCookie("username", username, 365);
}
}
}

The example above runs the checkCookie() function when

255
Window localStorage Property
- The localStorage and sessionStorage properties allow to save
key/value pairs in a web browser.
- The localStorage object stores data with no expiration date. The
data will not be deleted when the browser is closed and will be
available the next day, week or year.
- localStorage for all domain pages. Other domains have different
Storage objects.
• Syntax
- Syntax for SAVING data to localStorage.

localStorage.setItem("key", "value");

- Syntax for READING data from localStorage.

var lastname = localStorage.getItem("key");

- Syntax for REMOVING data from localStorage.

localStorage.removeItem("key");

- Syntax for REMOVING ALL saved data from localStorage.


localStorage.clear();

256
Window sessionStorage Property
- The sessionStorage object stores data for only one session (the data
is deleted when the browser tab is closed).
- A page session lasts as long as the browser is open and survives over
page reloads and restores.
- Opening multiple tabs/windows with the same URL
creates sessionStorage for each tab/window.

• Syntax
- Syntax for SAVING data to sessionStorage.

sessionStorage.setItem("key", "value");

- Syntax for READING data from sessionStorage.

var lastname = sessionStorage.getItem("key");

- Syntax for REMOVING saved data from sessionStorage.

sessionStorage.removeItem("key");

- Syntax for REMOVING ALL saved data from your computer.

sessionStorage.clear();

- The length property returns the number of items stored in the


browsers Storage Object for this particular domain.
- The length property belongs to the Storage Object, which can be
either a localStorage object or a sessionStorage object.

var x = localStorage.length;

257
Differences Between sessionStorage,
localStorage and Cookies
- calling localStorage on a document will return a Storage object;
calling sessionStorage on a document will return a
different Storage object. They function and are controlled
separately.
- localStorage and sessionStorage work on same-origin policy (same
domain, protocol and port).
- Cookies can be persistence or session, session stay as window/tab
are open, but persistence are saved on user’s disk until the expiration
date then deleted.
- localStorage and sessionStorage, the data is not sent back to the
server for every HTTP request, so it reducing the amount of traffic
between client and server.
- Cookies only allow you to store
strings. sessionStorage and localStorage allow you to store
JavaScript primitives but not Objects or Arrays.
- Cookies can be made secure by setting the httpOnly flag as true for
that cookie. This prevents client-side access to that cookie.
- Opening multiple tabs/windows with the same URL
creates sessionStorage for each tab/window while localStorage for
all domain pages.

258
Console
- The console object provides access to the browser's debugging
console. The specifics of how it works varies from browser to
browser, but there is a de facto (‫ )بحكم الواقع‬set of features that are
typically provided.

• console.assert()
- a method writes an error message to the console if the assertion is
false. If the assertion is true, nothing happens.
Syntax
console.assert(assertion, obj1 [, obj2, ..., objN]);
console.assert(assertion, msg [, subst1, ..., substN]); // C-like
message formatting

EX:

console.assert(number % 2 === 0, {number, errorMsg});


console.assert(false, 'the word is %s', 'foo');

• console.clear()
- a method clears the console if the environment allows it.

• console.count()
- a method logs the number of times that this particular call
to count() has been called.
Syntax
console.count([label]);

EX:

let user = "";

function greet() {
console.count(user);
return "hi " + user;
}

259
user = "bob";
greet();
user = "alice";
greet();
console.count("alice");

Output:
// "bob: 1"
// "alice: 1"
// "alice: 2"

• console.countReset()
- a method resets counter used with console.count() for that label
to 0. If omitted, countReset() resets the default counter to 0.
Syntax
console.countReset([label]);

• console.debug()
- a method outputs a message to the web console at the "debug"
log level. The message is only displayed to the user if the
console is configured to display debug output.
Syntax
console.debug(obj1 [, obj2, ..., objN]);
console.debug(msg [, subst1, ..., substN]);

• console.dir()
- a method displays an interactive list of the properties of the
specified JavaScript object. The output is presented as a
hierarchical listing with disclosure triangles that let you see the
contents of child objects.
Syntax
console.dir(object);

• console.dirxml()
- Displays an interactive tree of the descendant elements of the
specified XML/HTML element. If it is not possible to display as
an element the JavaScript Object view is shown instead. The

260
output is presented as a hierarchical listing of expandable nodes
that let you see the contents of child nodes.
Syntax
console.dirxml(object);

• console.error()
- Outputs an error message to the Web Console.
Syntax
console.error(obj1 [, obj2, ..., objN]);
console.error(msg [, subst1, ..., substN]);

• Console.group()
- Creates a new inline group in the Web Console log. This indents
following console messages by an additional level,
until console.groupEnd() is called.
Syntax
console.group([label]);

EX:
console.log("This is the outer level");
console.group();
console.log("Level 2");
console.group();
console.log("Level 3");
console.warn("More of level 3");
console.groupEnd();
console.log("Back to level 2");
console.groupEnd();
console.log("Back to the outer level");

Output:
This is the outer level
console.group
Level 2
▼ console.group
Level 3
More of level 3

261
Back to level 2
Back to the outer level

• Console.groupCollapsed()
- Creates a new inline group in the Web Console.
Unlike console.group(), however, the new group is created
collapsed. The user will need to use the disclosure button next
to it to expand it, revealing the entries created in the group.
Syntax
console.groupCollapsed([label]);

• Console.info()
- A method outputs an informational message to the Web
Console. In Firefox, a small "i" icon is displayed next to these
items in the Web Console's log.

Syntax
console.info(obj1 [, obj2, ..., objN]);
console.info(msg [, subst1, ..., substN]);

• Console.log()
- a method outputs a message to the web console. The message
may be a single string (with optional substitution values) or it
may be any one or more JavaScript objects.

Syntax
console.log(obj1 [, obj2, ..., objN]);
console.log(msg [, subst1, ..., substN]);

• Difference between log() and dir()


- console.log prints the element in an HTML-like tree.
- console.dir prints the element in a JSON-like tree.

262
• Logging objects
- Don't use console.log(obj),
use console.log(JSON.parse(JSON.stringify(obj))).This way
you are sure you are seeing the value of obj at the moment
you log it. Otherwise, many browsers provide a live view that
constantly updates as values change. This may not be what you
want.

• Console.table()
- Displays tabular data as a table.
- This function takes one mandatory argument data, which must
be an array or an object and one additional optional
parameter columns.
- It logs data as a table. Each element in the array (or
enumerable property if data is an object) will be a row in the
table.
- The first column in the table will be labeled (index). If data is an
array, then its values will be the array indices. If data is an
object, then its values will be the property names. Note that (in
Firefox) console.table is limited to displaying 1000 rows (first
row is the labeled index).

263
Syntax
console.table(data [, columns]);

EX:

console.table(["apples", "oranges", "bananas"]);

Output:

EX:

// an object whose properties are strings


function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
var me = new Person("John", "Smith");
console.table(me);

Output:

EX:

// an array of objects, logging only firstName


function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
var john = new Person("John", "Smith");
var jane = new Person("Jane", "Doe");
var emily = new Person("Emily", "Jones");

264
console.table([john, jane, emily], ["firstName"]);

Output:

• Console.time()
- Starts a timer you can use to track how long an operation takes. You
give each timer a unique name, and may have up to 10,000
timers running on a given page. When you
call console.timeEnd() with the same name, the browser will
output the time, in milliseconds, that elapsed since the timer
was started.

Syntax
console.time(label);

• Console.timeEnd()
- Stops a timer that was previously started by calling console.time().

Syntax
console.timeEnd(label);

• Console.timeStamp() – Not standardized


- This lets you correlate a point in your code with the other events
recorded in the timeline, such as layout and paint events.

Syntax
console.timeStamp(label);

• Console.trace()
- A method outputs a stack trace to the Web Console.

Syntax
console.trace( [...any, ...data ]);

265
EX: this will show you the call path taken to reach the point at which you
call console.trace()

function foo() {
function bar() {
console.trace();
}
bar();
}

foo();

Output:

bar
foo
<anonymous>
- global namespace is just an unnamed function in JavaScript, so that is
why it tells us it’s an anonymous function.

• Console.warn()
- Outputs a warning message to the Web Console.
Syntax
console.warn(obj1 [, obj2, ..., objN]);
console.warn(msg [, subst1, ..., substN]);

266
What is the difference between ViewState and
SessionState?
- 'ViewState': It is maintained at only one level that is page-level.
Changes made on a single page is not visible on other pages.
Information that is gathered in view state is stored for the clients only
and cannot be transferred to any other place.
- 'SessionState': It is maintained at session-level and data can be
accessed across all pages in the web application. The information is
stored within the server and can be accessed by any person that has
access to the server where the information is stored.
- SessionState has the tendency for the persistence of user-specific data
and is maintained on the server-side. This data remains available until
the time that the session is completed or the browser is closed by the
user. The session state is only valid for type objects.

Interview Questions:
Website 1
Website 2
Website 3
Website 4

267

You might also like