Page 1 of 62
Fact: It was
ECMA script all along→ ECMAScript all along
- Browser language to add
interactivity/dynamic effect→ interactivity and dynamic effects to webpages. - It is a single-threaded, cross-platform, object-oriented, concurrent programming language.
Data Types in JS
I. Numbers: Floating point numbers for decimal & integers
II. String: Sequence of chars used in text
III. Boolean: True / False
IV. Undefined: Data value of variable that does not have a value yet
V. Null: Non-existent (It is an object still!)
- JS is dynamic typing → Automatically assigns type to variables.
Note:
- In JS,
every number→ every number is floating-point. - Variable names can start with $, _, or any letter.
Type Coercion
- JS converts type from one to another automatically
e.g.console.log(Var1 + " " + Var2)
Variable Mutation
var age = 4;
age = "Hey";
Page 2 of 62
Falsy & Truthy Values & Equality Operators
- Falsy: undefined, null, 0, '', NaN
- Truthy: !Falsy
Note:
==does type coercion23 == '23' // true===does not23 === '23' // false
Functions
I. Function Declaration
function whatToDo(parameters) {
// ...
}
II. Function Expression
var whatToDo = function(parameters) {
// ...
}
- JS expressions are something that always return a value.
- JS statements are something that do some action.
- JS variables are
immutable→ mutable. - JS objects are mutable.
Page 3 of 62
Arrays
var names = ["a", "b", 23, true];
var years = new Array(10, "a", true);
names.length;
names[1];
// names[10]; // Has 6 empty in between?
names.push("x"); // Add at end
names.unshift("y"); // Add at front/start
names.pop(); // Remove from end
names.shift(); // Remove from start
names.indexOf("a"); // Returns first element that matches else returns -1
Objects & Properties
var john = {
firstName: "SK", // key-value pair
lastName: "Ag",
DOB: 2000,
isMarried: false
};
john.<property-key> = <value>;
john[<property-key>];
var john = new Object();
Page 4 of 62
Object Methods
var john = {
firstName: "",
age: ,
calcAge: function(arguments) {
return this.age;
}
};
john.calcAge(arguments);
Javascript and DOM
flowchart LR JavaScript -- Interaction/Manipulation --> DOM
Page 5 of 62
Basic JS
Background
- Called JS, but due to copyright issues, name is ECMAScript.
Statement vs Expressions
- Statements: do things
- Expressions: produce values
var foo; 3 + 7;
Semicolon
Optional in JS, but JS can guess wrong about end of statement→ Optional in JS, but JS can sometimes guess incorrectly about the end of a statement.
Identifiers & Variable Names
- Names that play various syntax roles in JS.
- A variable name is an identifier (can start with any Unicode letter, $, _).
Values
- All values in JS have some properties.
- Example:
str.length
- Example:
Values
| Primitives | Objects |
|---|---|
| boolean, numbers, | everything else |
| strings, null, | |
| undefined |
- Primitives: Compared by value
var x = 2; var y = 2; x == y; // true - Objects: Compared by reference
var obj1 = {}; var obj2 = {}; obj1 == obj2; // false obj1 = obj2; obj1 == obj2; // true
Page 6 of 62
Primitive Values
-
Content is compared by value
4 === 4; // true 4 === 5; // false -
Always immutable
Properties can't be added, removed, or changedstr.length = 1; // No change in str.length
Objects
I. Plain Objects
var s = {
name: "sk"
}
// Property: Value
II. Regular Expressions
/a+b+$/
III. Arrays
['a', 'b', 'c']
-
Content is compared by reference
var obj1 = {}; var obj2 = {}; obj1 === obj2; // false obj1 = obj2; obj1 === obj2; // true -
Always mutable
Page 7 of 62
Undefined & Null
- They have no properties 😞
var foo; // undefined if (x === undefined || x === null) { // ... } if (!x) { // ... } - Both undefined & null are considered falsy.
Categorizing Values using typeof and instanceof
| typeof | value |
|---|---|
| {} | object |
| true | boolean |
| undefined | undefined |
| null | object |
value instanceof constructor(doesn't work for primitives; use wrapper objects)var b = new Box(); b instanceof Box; // true {} instanceof Object; // true [] instanceof Array; // true null instanceof Object; // false
Page 8 of 62
Booleans
- Operators producing booleans:
- Binary logical:
&&,||(returns operand that is true) - Prefix logical:
! - Comparison: Equality (
===,!==,==,!=), Ordering (>,>=,<,<=)
- Binary logical:
| Values Interpreted as False | Values Interpreted as True |
|---|---|
| undefined, null, 0, NaN, '', (empty string) | everything else (e.g. {}, [], Infinity) |
Boolean({}) // true
Numbers
- All numbers in JS are floating-point
1 === 1.0 // true NaNis number!- Infinity:
"3"/0// Infinity
Operators
- Addition, -, /, *, %, ++, --
-x(negate value)+x(converts to number)+ '123' // Number 123
Page 9 of 62
Strings
- Can be declared via string literals (single/double quotes)
'+'operator concatenates the string+=can be used
String methods:
'abc'.slice(1) // 'bc'
'abc'.slice(1,2) // 'b'
'abc'.indexOf('bc') // 1
'abc'.toUpperCase() // 'ABC'
'abc'.trim()
Statements
I. Conditionals
if ( ) {
// ...
} else if ( ) {
// ...
} else {
// ...
}
- No need to use
{}if only a single statement. {}creates a block of zero or more statements.
switch (x) {
case 1:
// ...
break;
case 2:
// ...
break;
default:
// ...
}
Page 10 of 62
II. Loops
- for, while, do-while
Functions
I. Function Declaration
function add(x, y) {
return x + y;
}
- It is a mechanism in which function declarations are moved to the top of their scope before code execution (hoisting).
II. Function Expression
var add = function(x, y) {
return x + y;
}
- Function declarations are hoisted, but function expressions are not.
function bar() {
foo();
function foo() {}
}
// Works
function bar() {
foo();
var foo = function() {};
}
// Not
Page 11 of 62
Variable Arguments
function f() {
var args = ['a', 'b', 'c'];
args[0]; // 'a'
args[1]; // 'b'
}
- Can be accessed via the
argumentsarray (not an actual array, but array-like). - In case of too many arguments, excess are ignored but
argumentsarray knows them all. - In case of too few arguments,
undefinedis given to them.argumentsarray doesn't show undefined.
Exception Handling
function ex() {
throw new Error("I am an error");
}
try {
ex();
} catch (e) {
// ...
} finally {
// Not required but always executed whatever the result.
}
Strict Mode
- Enables more warnings & makes JS a cleaner language
'use strict';
Page 12 of 62
Variable Scoping & Closures
-
Variables are function-scoped, not block-scoped.
function foo() { var x = 5; if (x > 5) { var y = 2; } console.log(y); // No error, y is undefined if x <= 5 } -
Variable declarations are hoisted.
- Their declaration is moved to beginning but assignments stay put.
function foo() { console.log(n); if (false) { var n = 3; } } // Equivalent to: function foo() { var n; console.log(n); if (false) { n = 3; } }
- Introducing IIFEs (Immediately Invoked Function Expressions)
- Since variables are function-scoped, a scope can be created for variables, which makes it behave like blocks.
Page 13 of 62
if (true) {
(function() { // Open IIFE
var x = 3; // Inside
})(); // Close IIFE
}
// Required semicolon
Closures
- Functions stay connected to their birth scopes.
function createInc(startValue) { return function(step) { startValue += step; return startValue; }; } var inc = createInc(5); inc(1); // 6 inc(2); // 8 // startValue is changing
Page 14 of 62
Objects & Constructors
var obj = {
name: "Jam",
describe: function() {
return this.name;
}
};
obj.name; // "Jam"
obj.describe(); // shows value of "Jam"
obj.describe; // function
obj.name = "Hey";
obj.unknown; // undefined
"name" in obj; // true
delete obj.name; // removes property name
obj["home"]; // square box notations are used for string
// They allow computing the key of a property
Extracting Methods
Page 15 of 62
var func = obj.describe;
func(); // May work but 'this' becomes an error
// So, we
var func = obj.describe.bind(obj);
func(); // Same value as obj
// bind() creates a new function whose 'this' always has the given value
- Every function has its own variable
this
Constructors
- Later.
Page 16 of 62
Arrays
-
Sequence of elements that can be accessed via integers starting from zero.
var arr = [1, 2, 'a']; arr[0] = 5; arr.length; 2 in arr; // Does index 2 exist in array? arr.foo = 5; arr.foo = function() { console.log('Hey'); }; // This makes it array of elements + properties + methods "foo" in arr; // true -
All methods defined below work only on elements:
arr.slice(1
Page 17 of 62
Iterating Over Arrays
- Maybe ignored
arr.forEach(function(elem, index) { })
arr.forEach(function(elem, index) {
// your logic here
});
Page 18 of 62
Unit 7: Advanced JS
Statements & Expressions
-
Statements vs. Expressions:
- Statement
if (male) age = 10 else age = 11 - Expression
var age = (male ? 10 : 11);
- Statement
-
Expression that looks like a statement:
- Object literals (expressions) look like blocks (statements)
foo = bar(3,5) - Named function expressions look like function declarations:
function foo
- Object literals (expressions) look like blocks (statements)
Semicolons
i) Statements are terminated by semicolons.
ii) Except statements ending with blocks.
Page 19 of 62
Examples
while (a > 0) {
a--;
}
do {
a--;
} while (a > 0);
function foo() {}
var foo = function() {};
Strict Mode
"use strict";
-
Variables assigned without declaring create a global variable.
Strict mode prevents that. -
Functions must be declared at the top level of a scope.
-
Usually
thisiswindow→windowin browsers;
but in strict mode, it is undefined. -
In sloppy mode,
str.length = 3(any read-only property) can't be changed but can be written.
In strict, it gives error. -
Octal literals are not allowed in strict mode, eg
010.
Page 20 of 62
Ch 8: JavaScript's Type Systems
- Static: At compile time
- Dynamic: At runtime
i) JS is dynamically typed. Types of variables are generally not known → known at compile time.
ii) JS has a very limited kind of dynamic type checking, i.e., gives some kind of error or exception if a value used in an operation is incorrect.
- eg. ```js var foo = null; foo.prop // error
var bar;
bar.prop // No error, gives undefined instead
```
iii) Coercion: Implicit Type Conversion
- eg.
"3" * "4"
Result:12 - For null: it is coerced to 0 with numbers
- eg.
Number(null) = 0 5 + null = 5
- eg.
- For undefined: it is coerced to NaN
Number(undefined) = NaN5 + undefined = NaN
Page 21 of 62
Wrapper Objects for Primitives
Boolean, Number, String
-
eg.
typeof new String('abc') // 'object' new String('abc') === 'abc' // false new String('abc') == 'abc' // true String(123) // '123' -
'abc' instanceof String // false
(Never true for primitives)
| Wrap | Unwrap |
|---|---|
| new Boolean(true) | new Boolean(true).valueOf() |
| new Number(123) | new Number(123).valueOf() |
| new String('abc') | new String('abc').valueOf() |
-
JS uses
ToPrimitive()method:- If input is primitive, return it.
- If input is an object, call input.valueOf().
If result is primitive, return it. - Call input.toString(). If result is primitive, return it.
- Throw a TypeError.
Note: If preferred type is string, step 2 & 3 are swapped.
Page 22 of 62
Ch 9: Operators
All operators coerce their operands to appropriate type.
- eg.
[1,2] + [5,6] // "1,25,6"- Can be converted only to string
- Gives NaN with number
Assignment Operators & Compound Assignment
var x = value;
obj.property = value;
obj['propKey'] = value;
arr[index] = value;
// Compound: +=, -=, /=, *=, %=, >>=, <<=, &=, |=, ^=
>>>unsigned right shift
Equality Operators
| Operator | Description |
|---|---|
| === | Strict Equality |
| !== | Strict Inequality |
| == | Normal |
| != | Normal |
- Falls for
NaN == NaN undefined == null→ true- String & number: Converts string to number then strict
- Boolean & non-boolean: Converts boolean to number then strict
- Object & (string or number): Converts to primitive then strict
Page 23 of 62
Examples
"" == false // true
2 == true // false
2 == 1 // false
2 == false // false
1 == true // true
1 == 1 // true
+"" == false // true (0 == 0)
'abc' == true // false ('abc' == 1)
NaN === 1 // false
'123' == 123 // true
123 == '123' // true
'\n\t123\t\n' == 123 // true (This is a pitfall!)
{} == {} // false (different objects)
[] == 0 // true
Ordering Operators
<, <=, >, >=- Convert both to primitives.
- If both are strings, compare lexicographically.
- Otherwise, convert both to numbers & compare.
Plus Operator
- Converts both operands to primitives:
- If either is string, convert both to string & concatenate.
- Otherwise, convert both to numbers & return sum.
Check for:
+[] == 0
Page 24 of 62
VI. Special Operators
-
(?:),,,(void)?:<condition> ? <if_true> : <if_false>,<left>, <right>void <expr>: evaluates expression & returns undefined
void 4 + 7 // undefined + 7 = NaN void (x = 5) // undefined (x = 5)
VII. Operators on Numbers, Booleans & Objects
- This is explained later.
Page 25 of 62
Ch 10: Booleans
Boolean(value)→ converts to BooleanBoolean(new Boolean(false))→ returns true, as objects are truthy.
Logical Operators
&&(AND),||(OR), and!(NOT)
Binary Logical Operators
a) Value-Preserving:
- Always return either one of operands, unchanged.
js 5 || 3 // returns 5 6 && 3 // returns 3
b) Short-circuiting:
- The second operand is not evaluated if first operand determines the result.
Numbers
-
JS treats all numbers as floating point numbers (double-64 bit).
-
A number literal can be an integer, floating point, or hexadecimal:
35 3.141 0xFF // 255Exponential:
Page 26 of 62
Invoking Methods on Literals
123..toString()
123 .toString()
123.0 .toString()
(123).toString()
Converting to Number
-
Number(value)/+value -
undefined → NaN -
null → 0 -
A number → Number
-
Boolean → 0/1 (false/true)
-
String → parses number in string (
'1' → 1,'-0') -
Object → ToPrimitive()
parseFloat(str)
- Converts str to string
- Trims leading whitespaces
- Parses longest prefix that is a floating-point number
- eg.
parseFloat(true) // NaN parseFloat('true') // NaN parseFloat('') // NaN - So,
Number(value)is better.
Page 27 of 62
Special Number Values
i) NaN
-
The error value NaN is a number value.
- A number can't be parsed
- An operation failed
- One of operands is NaN
-
NaN === NaNis false -
isNaN(n)andtypeof n === 'number'check if it's a number
ii) Infinity
- The error value Infinity is caused by:
- Too large magnitude (eg.
2^1024) - Division by zero
- Too large magnitude (eg.
Note:
isFinite(n)
iii) Two Zeros
- Just consider them one.
Page 28 of 62
Internal Representation of Numbers
- Sign: 1 bit
- Exponent: 11 bits
- Fraction: 52 bits
- (64 bit total: 63-52, 51-0)
Value of Number:
Special Exponents:
-
-
Reserved 0s for NaN & Infinity
-
Now, due to numbers being stored as floating point, complex/non-integers may lead to imprecision. Use this function:
var EPSILON = Math.pow(2, -53);
function epsEq(x, y) {
return Math.abs(x - y) < EPSILON;
}
Convert 0.1 to 64-bit floating point representation
- 0.1 × 2 = 0.2 → 0.0
- 0.2 × 2 = 0.4 → 0.0
- 0.4 × 2 = 0.8 → 0.0
- 0.8 × 2 = 1.6 → 1.0
- 0.6 × 2 = 1.2 → 1.0
- ... = 0.00011...
So, (0.1)₁₀ = (0.00011...)₂
Mantissa = 10011001100110011001100... (52 bits)
Page 29 of 62
Exponent Calculation
- For 0, it's impossible to normalize, so JS stores:
- 0 → Fraction
- -1023 → Exponent
Math.pow(2, 1023) // large number
Math.pow(2, 1024) // Infinity
- Maximum value of double:
Safe Integer
Number.isSafeInteger(a)
- Imagine above DBL_MAX value with many precision errors. This happens for integers too.
Safe range
Note: Bitwise operations are 32-bit operations only.
- eg.
1 << 31 = 2^{31} 1 << 32 = 1 1 << 34 = 4
Page 30 of 62
Converting to Integers
Method 1: Math.ceil(), Math.floor(), Math.round()
Method 2: Inbuilt ToInteger() (not available)
Math.ceil(x + 0.5)
Method 3: 32-bit integers (conf) using bitwise
x | 0returns x as 32 bitn << 0signed 32-bitn >>> 0unsigned 32-bitn >> 0signed 32-bit
Method 4: parseInt(str, radix)
- Converts string to integer (base 10 by default)
- Except when string starts with 0x (base 16)
Operators
- Arithmetic:
+ - * / % ++ --%is remainder operator (not modulo)- Remainder operator = sign of first operand
- Modulo operator = sign of second operand
- eg.
-5 % 3 // -2 in JS (but normal call is 1) // so use Math.abs()
Page 31 of 62
II. Bitwise
& | ^ ~ << >> >>>
9 || 9.1(doesn't exist)< > << >> >>>(unsigned right shift)
Function: Number
i) Number('123')
- typeof Number('123') // 'number'
ii) new Number('123')
- object
Number Constructor Properties
Number.MAX_VALUE = 1.79769...e+308
Number.MIN_VALUE = 5e-324
Number.NaN
Number.NEGATIVE_INFINITY
Ch 12: STRINGS
I. Escape Characters
\',\"for escaping\b→ backspace\f→ form feed\v→ vertical tab\n→ new line\t→ horizontal tab\r→ carriage return
II. Character Access
s.charAt(ind)
s[ind]
Page 32 of 62
Converting to String
undefined → 'undefined'null → 'null'boolean → 'true'/'false'number → '3.141'object → call ToPrimitive(value, string)
Manually Converting to String
-
"" + value -
String(value) -
value.toString()(doesn't work for undefined & null)
Concatenating Strings
- The plus operator (details on previous page)
arr.join(separator)converts whole array to string
String Prototype Methods
string.charAt(ind)
string.charCodeAt(ind)
string.slice(start, end) // can handle negative values
string.substring(start, end) // can handle negative values
string.split(separator, limit)
Page 33 of 62
String Methods
Transform Methods
string.trim()string.concat(x, y, z)string.toLowerCase()string.toUpperCase()
Search & Compare Methods
string.indexOf(searchString[, start, stopString])(default is 0)string.lastIndexOf(searchString[, pos])(default is end)
Ch-13: Statements
for,while,for-in,if-else,do-whilefor-inis for objects
Ch-14: Exception Handling
try { ... }throw new Error("some error")catch/finally(both)finallyalways executes except when browser window/call stack stops ortryis not reached
Page 34 of 62
Error Constructors
- Error (Generic Constructor)
- All others are sub-constructors
- RangeError
- Indicates a numeric value has exceeded the allowable range
- Example:
new Array(-1)(invalid array length)
- ReferenceError
- Indicates invalid reference has been detected
- Example: unknown variable (not defined)
- SyntaxError / ParsingError
- TypeError
- Expected type is different than actual type of an operand
- Example:
undefined.foo(can't read property foo of undefined)
Properties of Error
messagenamestack(bottom to top)
Page 35 of 62
Ch-15: Functions
Three Kinds of Functions in JS
- Normal Method (
function, "normal function") - Constructor (
new Date()) - Method (
obj.method())
Params vs Args
function foo(param1, param2) { }
foo(3, 7); // args
Defining Functions
All functions are object instances of Function
funcinstanceofFunctionfunctioninstanceofObject
Types:
- Function Declaration (explained previously)
- Function Expression
- Function Constructor
- Evaluates JS code stored in string
- Example:
new Function('x', 'y', 'return x+y;')
Ch-16: Variable Scoping & Closures
- Code for "environment"
Page 36 of 62
Ch-??: Objects and Inheritance
Layout 1: Single objects
Layout 2: The prototype relationship b/w objects
Layout 3: Constructors - Factories for instances
Layout 4: Inheritance b/w constructors
Single Objects
- Refer to previous info
Converting Any Value to an Object
Object() // ?
new Object() // ?
- undefined → ?
- null → ?
- a boolean
bool→new Boolean(bool) - a number
num→new Number(num) - a string
str→new String(str) - object → obj
'this' as an Implicit Parameter
- For functions & methods
Note: Normal functions don't require
this(i.e. they have nothiscontext), but still:
function n() {
return this;
}
Returns global object
Page 37 of 62
Strict Mode
function n() {
"use strict";
return this;
}
Returns undefined
Methods
var obj = {
method: function() {
// use strict
return this;
}
}
Returns obj
Controlling Function Context: call(), apply(), bind()
Functions are objects, so they have the above mentioned methods.
graph TD Object1["object1 (prototype)"] --> Methods Object2["object2 (reference)"] --> Methods
call:
obj.sayHello("hi");
Function.prototype.call(obj, args); // 'this' value, not actual array
obj.sayHello.call(obj, args);
Page 38 of 62
apply:
func.apply(obj, [args]);
// actual array
bind:
Performs partial function application
var bound = func.bind(obj);
bound();
Partial Application
var bound2 = func.bind(obj, a, b);
bound2(c, d); // called with a, b, c, d
Example:
var cdt = {
firstName: "cat",
sayHi: function() {
setTimeout(function() {
console.log("Hi " + this.firstName);
}.bind(this), 1000);
}
}
this loses context, so we need to bind it:
cdt.sayHi.call(cdt);
cdt.sayHi.apply(cdt);
var bnd = cdt.sayHi.bind(cdt);
bnd();
Page 39 of 62
OOP
A programming model based around the idea of objects.
JS doesn't have "classes" built-in, so use functions & objects.
I. new Keyword
var obj = new House(arg1, arg2);
// is equivalent to:
function House(arg1, arg2) {
this.arg1 = arg1;
this.arg2 = arg2;
}
new keyword does:
- Creates empty object
- Sets
thiskeyword to be that empty object - Adds line "
return this" to end of function - Adds a property onto empty object called
__proto__
II. Prototypes
Page 40 of 62
graph TD Function -->|prototype| Person Person -->|constructor| prototype Person --|prototype|--> elite Person --|prototype|--> felt
- elite.proto === Person.prototype
- Person.prototype.constructor === Person
Note: Prototype is shared among all objects created by that constructor function.
Example:
- arr.proto === Array.prototype
graph TD arr -->|__proto__| Array.prototype Array.prototype -->|__proto__| Object.prototype Object.prototype -->|__proto__| null
Prototype Chain
Page 41 of 62
REACT (ES6 only)
JavaScript library for building user interfaces
Fundamentals of building Single Page Applications
1. Async Foundation
Callback Function
A function that is passed into another function as a parameter, then invoked by other function.
Higher Order Function
A function that accepts callback function as a parameter.
Callbacks are used for:
- Advanced Array Methods
- Browser Events
- AJAX
- React
Example: forEach function
Function Definition
function forEach(array, callback) {
for (var i = 0; i < array.length; i++) {
callback(array[i]);
}
}
Function Call
forEach(arr, function(number) {
console.log(number * 2);
});
Callback
function callback(current, index, array) { }
Page 42 of 62
Stack & Heap
- Stack: Keeps track of function invocations
- Heap: An area in memory where data is stored
setTimeout
A function that asynchronously invokes a callback after a delay in ms.
setTimeout(callback, timeId)
cancel setTimeout → clearTimeout(timeId)
setInterval
A function that continually invokes a callback every X ms.
setInterval(callback, intervalId)
cancel → clearInterval(intervalId)
Promise
A promise is an object that represents a task that will be completed in future.
var p1 = new Promise(function(resolve, reject) {
resolve([1, 2, 3, 4]);
reject("error"); // assign code
});
p1.then(function(data) {
console.log(data);
})
.catch(function(data) {
console.log(data);
});
Page 43 of 62
Promise Chaining
To avoid callback hell in async code (i.e., hard to read).
Returning Promise
p1.then(function(data) {
return new Promise(function(resolve, reject) {
// async resolve or reject
});
})
.then(function(data) {
// ...
});
Returning Data
p1.then(function(data) {
return data * 2;
})
.then(function(data) {
console.log(data);
});
In practice, you will be given promises that are returned to you.
JSON.parse
JSON.parse(...)
Converts JSON data to JavaScript object.
Promise.all
Promise.all([p1, p2, ...])
.then(function(promiseArr) { });
Page 44 of 62
II. Fetch
fetch(url, {
method: 'post',
body: JSON.stringify({
name: 'blue',
login: 'bluecat',
}),
headers: { ... }
})
.then(function(res) { ... })
.catch(function(err) { ... }) // only runs when there is problem with request (e.g., URI doesn't exist or no Internet)
III. Ajax
$.ajax({
method: ...,
url: ...,
data: ...,
headers: ...
})
.done(...)
.fail(...)
.always(...)
IV. Axios
axios.get(url)
.then(...)
.catch(...)
Page 45 of 62
V. Advanced JS Functions
(A) Advanced Array Methods
forEach
Iterates through an array.
Runs a callback function on each value in array.
Returns undefined.
arr.forEach(function(value, index, array) { });
map
As forEach returns undefined, we may need to transform array, so we use map.
- Creates a new array
- Iterates through an array
- Runs a callback function for each value in array
- Adds the result of that callback function to new array
- Returns new array
arr.map(function(val, ind, arr) {
return value * 2;
});
// [2, 4, 6]
function map(arr, callback) {
var newArr = [];
for (var i = 0; i < arr.length; i++) {
newArr.push(callback(arr[i], i, arr));
}
return newArr;
}
Page 46 of 62
filter
- Creates new array
- Iterates through an array
- Runs a callback function on each value in the array
- If callback returns true, element is added to new array, else not
- Returns new array
arr.filter(function(val, ind, arr) {
return true/false;
});
function filter(arr, callback) {
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (callback(arr[i], i, arr)) {
newArr.push(arr[i]);
}
}
return newArr;
}
some
- Iterates through an array
- Runs a callback on each value in the array
- If callback returns true for at least one single value, returns true; else returns false
arr.some(function(val, ind, arr) {
return true/false;
});
function some(arr, callback) {
for (var i = 0; i < arr.length; i++) {
if (callback(arr[i], i, arr)) {
return true;
}
}
return false;
}
Page 47 of 62
every
- Opposite of some
reduce
- Accepts a callback function & an optional second parameter
- Iterates through an array
- Runs a callback on each value in the array
- The first parameter to the callback is either first value in array or optional second parameter
- The first parameter to the callback is called accumulator
- The returned value from callback becomes new value of accumulator
arr.reduce(function(accumulator, nextValue, index, array) {
// whatever returned inside here will be the value of acc in next iteration
}, optional_second_parameter);
Page 48 of 62
Example:
var arr = [1, 2, 3, 4, 5];
arr.reduce(function(acc, nextVal) {
return acc + nextVal;
});
| acc | nextVal | returnedValue |
|---|---|---|
| 1 | 2 | 3 |
| 3 | 3 | 6 |
| 6 | 4 | 10 |
| 10 | 5 | 15 |
Returns 15
(B) Closures
A closure is a function that makes use of variables defined in outer function that have previously returned.
function outer(a) {
return function inner(b) {
return a + b;
}
}
outer(5)(5); // 10
var storeOuter = outer(5);
storeOuter(10); // 15
Closures can help for private variables.
Page 49 of 62
Closures and Privacy in JavaScript
Example: Counter Closure
function counter() {
var count = 0;
return function inner() {
count++;
return count;
}
}
- Usage:
var counter1 = counter();
counter1(); // 1
counter1(); // 2
var counter2 = counter();
counter2(); // 1
counter2(); // 2
More Privacy: Factory Pattern
function classRoom() {
var instructors = ["A", "B"];
return {
getInstructors: function() {
return instructors.slice();
},
addInstructor: function(instructor) {
instructors.push(instructor);
return instructors.slice();
}
}
}
Page 50 of 62
(C) ES2015 (ES6) Features
(i) const
- Can't redeclare, also
can't→ can't reassign. - Can mutate if it is an object.
const aone = [1, 2, 3, 4];
aone.push(5);
(ii) let (Block Scope)
- Can't redeclare, but can reassign.
if (variable === "Hey") {
let number = 1;
}
newVar; // Not defined
(iii) Template Strings
- Use backticks
`. - Can do multi-line strings.
(iv) Arrow Functions
var add1 = (a, b) => {
return a + b;
}
Or single-line:
var add2 = (a, b) => a + b;
Page 51 of 62
Arrow Functions: this and arguments
- Arrow functions don't get their own
thiskeyword. - They get the value of
thisfrom just outside its context. - Arrow functions don't get an arguments array.
Example:
var instructor = {
firstName: "Elie",
sayHi: function() {
setTimeout(function() {
console.log(`Hello ${this.firstName}`);
}, 1000); // use bind(this)
}
};
instructor.sayHi(); // Hello undefined (use bind keyword)
But with arrows:
var instructor = {
firstName: "Elie",
sayHi: function() {
setTimeout(() => {
console.log(this.firstName); // gets context from here
}, 1000);
}
};
// "Elie"
(v) Default Parameters
function add(a = 10, b = 20) {
return a + b;
}
Page 52 of 62
(vi) for...of Loop
var aone = [1, 2, 3, 4, 5];
for (let val of aone) {
console.log(val);
}
- Can't be used on objects because it doesn't have
Symbol.iteratormethod implemented. - Can't access an index.
(vii) Rest Operator
function printArg(a, b, ...c) {
console.log(a); // 1
console.log(b); // 2
console.log(c); // [3, 4, 5]
}
printArg(1, 2, 3, 4, 5);
(viii) Spread Operator
var aone = [...aone1, ...aone2];
- Spreads array.
Page 53 of 62
9. Object Shorthand Notation
var instructor = {
firstName,
lastName
};
var instructor = {
sayHi() {
return "Hello";
}
};
10. Destructuring
- Extracting values from data stored in objects & arrays.
var { firstName, lastName } = instructor;
var { firstName: first, lastName: last } = instructor;
Array Destructuring
var [a, b, c] = aone;
// Example: swapping values
[a, b] = [b, a];
Page 54 of 62
11. OOP in JavaScript
i) Class
newkeyword required.- Abstraction of constructor functions & prototypes.
- Creates a constant – can't be redeclared.
- Doesn't hoist.
- Still use
newkeyword.
class Student {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
var elie = new Student('Elie', 'Schoppik');
Instance methods
class Student {
sayHello() {
return "Hello";
}
}
// Mimic of student.prototype.sayHello
Class methods
class Student {
static isGood(obj) {
return obj.isGood;
}
}
// Mimic of Student.isGood
Page 55 of 62
ii) Inheritance
class Person {
// ...
}
class Student extends Person {
// ...
}
// Mimic of Student.prototype = Object.create(Person.prototype);
iii) Super
class Student extends Person {
constructor(firstName, lastName) {
super(firstName, lastName);
}
}
12. Maps (HashMap of C++)
- Keys can be of any data type, unlike objects.
var firstMap = new Map();
firstMap.set(key, value);
firstMap.delete(key);
firstMap.size;
firstMap.get(key);
firstMap.forEach(v => console.log(v));
firstMap.values();
firstMap.keys();
- Can be iterated.
Page 56 of 62
13. Sets
- All values in a set are unique.
- Any type of value can exist in a set.
- Created using
newkeyword.
var s = new Set([1, 2, null, 4]);
s.add(key);
s.delete(key);
s.has(key);
s.size;
- Can be iterated.
14. Generators
- A special kind of function which can pause execution & resume at any time.
- Created using a
*. - When invoked, a generator object is returned, with keys of
value&done.
function* pauseAndReturn(num) {
for (let i = 0; i < num; i++) {
yield i;
}
}
var gen = pauseAndReturn(10);
gen.next(); // { value: 0, done: false }
gen.next(); // { value: 1, done: false }
gen.next(); // { value: undefined, done: true }
Page 57 of 62
(D) ES2016 & ES2017
1. Exponentiation Operator
Math.pow(2, 4);
2 ** 4;
a **= 4; // a = a ** 4
2. Array Includes
aone.includes(key);
str.includes(subStr);
3. padStart & padEnd
str.padStart(arg1, '!'); // pad from start, default is whitespace
str.padEnd(arg2, '!');
4. Async Functions
- Simplify writing async code, specifically Promises.
async function first() {
return "first";
}
first().then(val => console.log(val)); // returns promise
Page 58 of 62
Await
- Reserved keyword used inside async functions.
- Pauses execution of async function; is followed by Promise.
- Waits for Promise to resolve & then resumes the async function execution & returns resolved value.
- (Similar to
yieldwith generators.)
async function getMovieData() {
console.log("Start");
var movieData = await $.getJSON();
// waits for promise to be resolved
console.log("All done!");
console.log(movieData);
}
getMovieData();
- Methods in object can also be async.
Note: Await assumes that promise is always resolved.
So, for errors, use try/catch.
try {
await ...;
} catch (e) {
console.log(e);
}
Page 59 of 62
- We can use await with
Promise.all().
5. Object Rest & Spread
Rest
var instructor = { first: 'elie', last: 'sch', numSt: 3 };
var { first, ...data } = instructor;
// first: 'elie'
// data: { last: 'sch', numSt: 3 }
Spread
var instructor2 = { ...instructor, first: "tim", age: 18 };
// Overwrite
Page 60 of 62
TypeScript
Ways to Declare a Type/Object
- Using Interface:
interface Point {
readonly x: number;
y: number;
}
- Using Type:
type Point = {
x: number;
y: number;
}
-
You can specify optional parameters using
?. -
Extending interface:
interface ColorfulCircle extends Colorful, Circle {}
// or intersection
type ColorfulCircle = Colorful & Circle;
- Generics:
function doWork<Type>(arr: Array<Type>): Type[] {
// ...
}
Page 61 of 62
interface Box<Type> {
contents: Type;
}
// or
type Box<Type> = {
contents: Type;
}
Note: Array is a built-in generic type/interface.
-
We now also have:
Map<K, V>Set<T>Promise<T>
-
Generic classes:
class GenericNumber<NumType> {
zero: NumType;
add(x: NumType, y: NumType): NumType { ... }
}
- Adding Constraints:
interface OurConstraint {
length: number;
}
function func<Type extends OurConstraint>(arg: Type) {
console.log(arg.length);
}
Page 62 of 62
- Special Types:
ReturnType<typeof func>
ReadOnlyArray<T>
keyof
- Classes:
class XYZ {
public n: string;
protected y: number;
private z: string;
get() { }
set() { }
static { }
}
// Note: TS has no static classes.
- A TS way of handling "this":
class MClass {
name = "xyz";
getName(this: MClass) {
return this.name;
}
}
References & Related Topics
- MDN Web Docs: JavaScript
- ECMAScript Language Specification
- JavaScript: The Good Parts by Douglas Crockford
- Related: TypeScript, ES6+, DOM Manipulation, Functional Programming in JS, Async Programming (Promises, async/await)