Introduction
Extensive JavaScript notes. CliffsNotes version.
JavaScript Syntax
JavaScript Comments
A line that begins with // is a comment.
A multi-line comment has the form:
/*
*/
Strict Mode
When strict mode is in effect, the JavaScript interpreter will emit errors for unsafe syntax. Invoke strict mode by placing the following statement at the top of a JavaScript file or at the top of a JavaScript method:
“use strict”;
JavaScript Statements
JavaScript statements are case sensitive. Statements always end with a semicolon: ;
Code Blocks
Multiple JavaScript statements can be enclosed in a code block as follows:
{
….
}
Whitespace
The JavaScript interpreter disregards whitespace in statements.
JavaScript Variables
In JavaScript, variables hold values. Variable names are case sensitive. A variable can begin with a $ or an underscore _. Digits are allowed in a variable name but a variable name cannot start with a digit.
var home;
In the above statement, the variable home is defined but not initialized (does not have a value assigned to it). JavaScript is loosely typed, so home can be assigned a value of any type at any time.
A JavaScript variable may be declared and initialized in one statement:
var choice = 5;
var home = “echo lake”;
Style
The default JavaScript style is to use camel case: example, blueStallion.
Variable Scope
If a variable is defined with the var keyword then its scope is confined to the enclosing code block. If the variable is defined without the var keyword then it is a global variable.
Variables With Global Scope: A variable which is declared outside of all functions, with or without the var keyword, always has global scope.
In the following example, treehouse is a global variable:
function myfunc {
treehouse = “birch”;
// treehouse is a global variable
}
Scope Rules
- A variable declared outside all functions is global (even if the var keyword is used) 2.A variable declared with the keyword var inside a function has it's scope confined to the enclosing block or the function body.
- A variable defined without the var keyword inside a function has global scope.
- A global variable can be defined and initialized in one step as follows:
treehouse = “bird”;
The Environment
The environment of a JavaScript program is the values of it's variables.
The Standard Browser Environment
The Standard Browser environment contains a few useful functions. These are:
Alert Box
The function alert prints the value of it's argument (in a dialog box) . Example:
alert(“Hello”);
Confirm Dialog
The confirm dialog presents a dialog box with 'yes' and 'no' options. When the user presses a button, the function returns either true or false.
confirm(“Save File?)
Prompt Dialog
The prompt function presents a dialog in which the user can give an answer. The first parameter is a text string which will be presented to the user. The second parameter is the string with which the user's answer will begin.
prompt(“What is your favorite color?”, “my favorite color is: ”)
The user is presented with a text input box. The function returns the user's answer prepended by the second argument.
JavaScript Data Types
There are 7 primitive JavaScript data types:
1.undefined
2.null
3.boolean
4.number
5.string
6.BigInt
7.Symbol
And:
Objects
Type Introspection
Variables are loosely typed in JavaScript. That is they can hold a value of any data type.
We need a way to determine the type of data that a variable holds. This information is provided by the typeof operator. The typeof operator returns the type of data that a variable contains as a string:
typeof 4.1;
// “number”
typeof “hello world”;
// “string”
typeof myObject;
// returns “object”
We can also use the syntax :
typeof(my_var);
The typeof operator returns one of six values: undefined, boolean, string, number, object or function.
The Undefined Type
In Javascript a variable which is defined but not initialized is assigned the value undefined. If the typeof operator is called on this variable it returns undefined.
A statement such as: var home declares the home variable but does not assign a value to the variable. So in this case the typeof(home) is undefined and the value assigned to home is “undefined”.
The test home == undefined is a valid test.
The Null Type
The null type has a single value null. When a variable is defined and is expected to hold a
value later on, the variable should be assigned the null value. This lets us perform tests such
as:
if ( car != null ) {
}
Boolean Data Type
The boolean data type has two possible values: true or false. These are not the same as 0
or 1.
The function Boolean() automatically converts a variable to a boolean value.
conversions are as follows:
Boolean Conversions
Data Type Values | Converted to True Values | Converted to false |
---|---|---|
string | Non-empty strings | “” - the empty string |
number | Any non-zero number | 0 and NaN |
object | Any object | null |
undefined | N/A | undefined |
boolean | true | false |
Boolean() is important because many control flow statements implicitly use it to test for true or false:
var message = 'hello world'
if Boolean(message) {
}
Numbers
JavaScript has a single Number type which is used to represent numbers.
Ordinary integers can be expressed as: var iNum = 5;
Hexadecimal numbers have a leading 0x : var iNum = 0x5FA3 (this is case insensitive).
Floating Point Numbers
JavaScript treats any number with a decimal point and a string of numbers after the decimal point as a floating point number. Floating point numbers are 64 bits long.
One bit is used for the sign and 11 bits are used for the fractional part of the number. Thus52 bits are available to represent the whole number.
Numbers can be expressed in scientific notation such as: 2.998e8
That is : 2.998 * 10**8
In Javascript everything is an object and thus numbers are objects which have methods.
Positive And Negative Infinity
The largest number that can be represented in Javascript is denoted by:
Number.MAX_VALUE
The smallest number is represented by:
Number.MIN_VALUE;
We can test whether a number is within the maximum and minimum range with: isFinite().
When a number is below the lowest possible value it is given the value : -Infinity and whenit is more than the maximum value it is denoted as: Infinity. No arithmetic operations can be performed on these values.
NaN
When an arithmetic operation is performed and a number is expected, the result is set to
NaN when the result is something other than a number (errors excepted). NaN (Not A
Number) is the value which results when an illegal arithmetic operation is performed such as division by 0.
NaN is not equal to any number including itself.
IsNaN()
The function isNaN(x)
tests whether the operand is a number or can be converted to a
number. Thus isNan(“10”) returns false. isNaN('green') returns true.
Number Conversion Functions
There are three functions to convert variables of various data types to numbers: Number(),parseInt() and parseFloat().
Number()
Number is designed to take arbitrary operands. The Number function converts its argument into a number, for example: Number(“56”), Number(“blue').
It's rules are as follows:
operand | returned value |
---|---|
Boolean: true or false | 1 or 0 |
number | Returns the operand |
null | 0 |
undefined | NaN |
String with numbers only | Returns the operand |
Empty string | 0 |
Floating point number in string | Floating point number |
valid hexadecimal number in string | Decimal number |
Other Strings | NaN |
parseInt()
parseInt converts a string to an integer or floating point representation.
parseInt works as follows. Leading white space in the string is ignored. If the first character is not +, - or a number, parseInt returns NaN. parseInt() continues examining numbers until it reaches the end of the string or a non-number character. It then stops and returns the result. Thus parseInt(“1234blue”) returns 1234.
parseInt recognizes hexadecimal numbers. Thus parseInt(“0xFA”) is recognized.
parseInt(“”) returns NaN.
parseInt() can take an optional second argument which is the radix which is to be used in
the conversion:
parseInt(“310”, 4). Here the radix is 4.
parseFloat()
parseFloat generates a floating point number from a string until a non-numeric character is reached. It does not recognize any radix other than 10.
The String Data Type
A string is a sequence of characters enclosed in single or double quotation marks. Here is
an example:
var myvar = 'this is a string'
The Javascript interpreter does not do any string interpolation.
Special characters can be included in a string if they are preceded by a backslash escape character, for example: \n – newline: \ - backslash, \” - quote and \t – tab.
String Length
The length of a string can be obtained with the length property: “hello world”.length
String Concatenation
The + operator can be used to concatenate strings.
“my ” + “new ” + “shoes”
// “my new shoes”
var my_str = “Shoes”;
var new_var = “my new ” + mystr; // “my new Shoes”
In string addition, when one of the variables is a number, the number is cast to a string before the string addition is performed:
my_var = 3.5 + “2.0”; // “3.52.0”
charAt
Given a string str, str.charAt(x) returns the character at the xth position. The charAt index starts at 0.
When the index extends beyond the end of the string, charAt returns “”.
slice
Given a string str, str.slice(x, y) returns the substring starting at position x which is y characters long.
When the length parameter y extends beyond the end of the string, slice simply truncates y to extend to the end of the string.
If slice is given only one parameter it returns the substring from the starting index position to the end of the string.
substr
str.substr(x, y)
extracts the substring starting at index position x of the string and up (but
not including the portion of the string starting at index position y.
“hello world”.substr(2, 5); // llo
Case Conversion
The function toUpperCase() converts a string to upper case. For example:
toUpperCase(“hello”). The function toLowerCase() converts a function to lower case.
Conversion To A String
The function toString converts an object to a string:
var val = 11;
val.toString // “11”
var val = true
val.toString // “true”
This method is not available for null or undefined. If you are not sure that the object is null or undefined, use String(). String(operand) returns “null” if the operand is null and returns “undefined” if the operand is undefined.
toString can take a radix argument to be used in the conversion of a number. For example: 167.toString(16).
String Comparison
Strings are compared lexicographically. Upper case letters are always less than lower case letters. The implementation uses Unicode which assigns a number to each character.
aardvark > Zebra // true
HTML Escape Function
The escape function converts an ASCII string to URL encoded format. This encodes
characters which have a special meaning in HTTP such as spaces, colons, slashes etc.
var encodedStr = escape(“my string”)
For non-ASCII strings it is necessary to use: encodeURI and decodeURI.
The Object Type
Custom objects are created with the new operator:
var obj = new Object();
After this properties and methods can be added to obj.
All objects have the toString method which returns the string representation of the object.
Objects also have the valueOf method which returns the number, boolean or string
representation of the object.
Arithmetic Operators
The arithmetic operators are: *, /, %, + and - .
Multiplication and division have higher precedence than addition and subtraction. When
arithmetic operators have the same precedence, they are applied left to right. The
precedence of operations can be changed by using parentheses.
AutoIncrement And AutoDecrement
JavaScript uses C's increment and decrement operators ++ and -- . These can be applied before or after a variable: ++a, a++, --a, a--. The prefix version will increment or decrement the variable before evaluating the expression. The postfix version increments or decrements the variable after evaluating the expression.
These operators can be used on numbers, booleans, strings or objects. For booleans true is converted to 1 and false to 0.
If a string can be converted to a number, then the string is first converted to the number and then the increment or decrement operator is applied. If the string cannot be converted to a number, then the value of the auto-increment or decrement operation is set to NaN.
The auto-increment and auto-decrement operators can be applied to objects. First the object is converted using the valueOf operator. If the operand cannot be converted to a number then the result is NaN.
Unary Operators : - , +
The unary operators can be applied to numbers, booleans, strings and objects. When
applied to a string, boolean or an object, the object is first converted to a number using the valueOf function and then the unary operator is applied to the result. If the operand cannot be converted to a number then the result is NaN.
Modulus Operator
The modulus operator % is the remainder after dividing two numbers. % has the same
precedence as * and /.
Constants
A variable can be made read only with the const modifier:
const var readonly = 3.5;
Assignment Operations
nvalue *= 3; // nvalue = nvalue * 3;
nvalue -= 5;
nvalue /= myvar;
nvalue %= modulii;
Logical Operators
The logical operators are: &&, || and !
The precedence of logical operators is shown below with precedence from highest to lowest (operators in parentheses have equal precedence and evaluated left to right):
!, !=, ===, (<, >, &&, ||)
Unary ! Operator
The logical not operator: ! can operate on any operand. First the operand is converted to a boolean value and then it is negated. It flips the logical value. This operator behaves as follows:
Operand is an object | Returns false |
Operand is an empty string | Returns true |
Operand is a non-empty string | Returns false |
Operand is a non-zero number | 0 |
Operand is infinity | Returns false |
Operand is null | Returns true |
Operand is NaN | Returns true |
Operand is NaN | Returns true |
Operand is undefined | Returns true |
Logical And
The logical AND operator is represented by &&. The operator can take any type of
operand. The result may not be a boolean value. This operator may return the result
without evaluating the entire expression (short circuit evaluation).
&& will not evaluate it's right hand side expression if the left side evaluates to false. && is a short-circuited operation.
The following evaluation rules apply if one of the operands is not a boolean:
- If the first operand is false, then false is returned. The second operand is ignored.
- If both operands are true then true is returned.
- If the first operand is false and the second is true then false is returned
- If the first operand is an object then the second operand is always returned
- If both operands are objects then the second object is always returned
- If either object is null then null is returned
- If either object is NaN then NaN is returned
- If either object is undefined then undefined is returned
Logical OR Operator
The logical OR operator is represented by ||. If both operands are booleans then the
operator returns false only if both of the operands is false.
The following additional rules apply:
- If the first operand is an object then the first object is returned
- If the first operand evaluates to false then the second operand is returned
- If both operands are null then null is returned
- If both operands are NaN then NaN is returned
- If both operands are undefined then undefined is returned
Multiplicative Operators
The multiplicative operators are : *, / and %. If one of the operands is not a number then
the Number() function is used to perform a type conversion.
The following rules apply:
1.For number operands the ordinary rules apply, except that for out of bound
results, +infinity or -infinity may be returned.
2.If infinity is multiplied by 0 then NaN is returned.
3.If infinity is multiplied by a number other than zero then +infinity or -infinity isreturned.
4.If infinity is multiplied by infinity the result is infinity
The Division Operator
The division operator (/) divides two operands.
For numbers ordinary division is performed but if the result is out of bounds then +infinity or -infinity is returned. If one of
the operands is not a number then the Number() function is used to convert the operand.
The following special rules apply:
- If one or both operands are NaN then NaN is returned
- If infinity is divided by infinity then NaN is returned
- If 0 is divided by 0 then NaN is returned
- If a non-zero finite number is divided by 0 then +infinity or -infinity is returned
Modulus Operator
The modulus operator is represented with %. If one of the operands is not a number then the Number() function is applied to convert it to a number.
The following special rules apply:
- If the dividend is infinite and the divisor is a finite number then NaN is returned
- If the dividend is a finite number and the divisor is zero then NaN is returned
- If infinity is divided by infinity then NaN is returned
- If the dividend is a finite number and the divisor is infinite then the dividend is returned 5.If the dividend is zero and the divisor is a finite number then 0 is returned
Additive Operator
If both operands are numbers then the ordinary rules of addition apply. The following special rules are applicable:
- If either operand is NaN then the result is NaN
- If -Infinity is added to +Infinity then the result is NaN
- If -infinity is added to -infinity then the result is +infinity
- If +infinity is added to +infinity then the result is +infinity
- If -0 is added to +0 the result is +0
- If -0 is added to -0 then the result is -0
String Addition
If both operands are strings then + will concatenate the strings. If one of the operands is a string, then the other operand will be converted to a string and the two strings concatenated. This involves calling the toString() function for the operand which is not a string.
Subtraction Operator
For ordinary numbers, subtraction follows the ordinary rules. The following special rules apply:
1.If either operand is a NaN then the result is NaN
- If +infinity is subtracted from +infinity then the result is NaN
- If -infinity is subtracted from -infinity the result is Nan
- If -infinity is subtracted from +infinity then the result is infinity
- If +infinity is subtracted from -infinity then the result is infinity
- If -0 is subtracted from +0 the result is -0
- If -0 is subtracted from -0 the result is +0
- If either operand is a string, boolean, null or undefined, it is converted to a numberusing Number() 9.If either operand is an object, it's valueOf() function is called. If the object doesnot have a valueOf() function then the toString() function is called and the resulting string is converted to a number.
Relational Operators
The relational operators are : >, < , >= and <=. Relational expressions return true or false.
The following special rules apply:
- If both operands are numbers, the ordinary comparison is made
- If both operands are strings then the strings are compared lexicographically
- If one operand is a number, the other operand is converted to a number
- If one operand is a boolean it is converted to a number
- If one operand is an object, it is converted to a number using valueOf(). If valueOf() is unavailable, toString() is used.
If one of the operands is NaN then the result will be false. For string comparisons, the ASCII character codes are compared. Thus “Z” is less than “a” for example.
Equality Operator
The equality operator is ==. The inequality operator is !=. Type coercion is performed before an equality or inequality test is made.
The following rules are applied:
One of the operands is a boolean convert the boolean into a number (0 or 1)
One operand is a string and the other is
a number attempt to convert the string to a number
One of the operands is an object and the
other is not convert the object using the valueOf() funtion
null == undefined returns true
One of the operands is NaN returns false
Both operands are objects return true only if they point to the same
object
“NaN” == NaN false
NaN == NaN false
Undefined == 0 false
Identically Equal And Not Identically Equal Operators
The identically equal operator is === and the not identically equal operator is !==. These operators work like == and != but do not perform any type conversion before the equality test is made.
Since type coercion is not performed, null === undefined is false.
The Conditional Operator
The conditional operator has the form:
var result = (boolean expression) ? val1 : val2;
This has value val1 if the boolean expression is true and val2 otherwise .
The Assignment Operator
The assignment operator has the form: x = val. The right hand side value is assigned to the variable on the left.
Compound assignments such as: x += 10, x *= 5, x /= 8, x %=6 can be made.
Comma Operator
The comma operator allows more than one expression to be evaluated in a statement:
x = 1, y = 7, z = 9;
Expressions And Statements
An expression is a piece of code that produces some value. A statement is a one or more expressions that ends in a semicolon:
1 + 5;
Blocks: A block is a group of statements enclosed in parentheses.
Control Flow
if Processing
This is the basic if statement:
if (some expression) {
}
The if condition must be in braces. The conditionally evaluated block of code must be enclosed in braces unless it is a single statement.
This is a multi-way if test:
if (some expression) {
}
else if (some expression) {
}
else if (some expression) {
}
else {
}
The Switch Statement
This is a multi-way switch test similar to the switch found in C. It has the form:
switch (expression)
{
case first_test_condition:
statements;
[break;]
case second_test_condition:
statements;
[break;]
default:
statements;
}
The expression in the switch statement is evaluated. It is then compared with the first test condition. If there is a match, the statements following the label are executed. If there is a break then the processing terminates. Otherwise the next expression is evaluated. If the processing does not terminate with a break statement, the second test condition is evaluated and so forth. If no case match is found then the default statements are executed providing that a default block exists. To break the fall through the switch a matching expression must have a break statement. Where two or more case statements execute the same block of statements, we can use the shorthand:
case expression1:
case expression2:
case expression3:
statements;
Important: The switch statement evaluates expressions using the identically equal to operator. No type coercion is performed.
A Switch Example
Switch (prompt(“what is the weather like”, “...”) {
case “rainy”:
alert(“bad weather');
break;
case “sunny”:
alert(“Nice weather")
break;
default:
alert(“not known”);
}
Ternary Operator
The ternary operator has form:
var res = condition ? val1 : val2
Example:
var my_var = 3
var q_var = my_var > 0 ? true : false
While Loop
The form of this loop is:
while (test) {
}
The test condition must be enclosed in parentheses and the block of code must be in braces unless it is a single statement. The test condition will be converted with the Boolean() method before invoking the test.
Example:
var ctr = 1;
while (ctr < 10) {
ctr = ctr + 1;
}
Do While Loop
do {
} while ( expression );
The loop test must be enclosed in parentheses. The block of code executed by the loopmust be enclosed in braces.
The do while loop will execute the body of the loop at least once.
Example:
var ctr = 1;
do {
...
ctr = ctr + 1;
} while (ctr < 10);
For Loops
The basic form of the for loop is:
for (initialization; condition; post-loop expression) {
}
Example:
var val = 5;
for ( var i = 0; i < val; i++) {
}
This loop is identical to the for loop in C.
The test must be enclosed in parentheses and the block of code to be executed must beenclosed in braces.
The loop test is performed before the loop body is executed. After the loop body is
executed, the post-loop expression is evaluated.
Example:
for (var ctr = 0; ctr < 10; ctr = ctr + 1) {
alert(ctr);
}
Empty Loop Statement
The initialization, control expression and the post-loop expression are all optional. An infinite loop has the form:
for (;;)
{
...
}
Labeled Statements
Labeled statements have the form:
label:
statements
Break And Continue Statements
The break statement breaks out of a loop:
var sum = 20
while (var index = 0; index < 100; index++) {
if (index == sum)
break;
}
If the break statement is executed, the post-loop expression will not be executed.
Continuing To The Next Iteration
for (var ctr = 0; ctr < 10; ctr = ctr + 1) {
continue;
}
Both break and continue can have label arguments. This is useful to break out of nested loops:
for ( i = 0; i < 10; i++) {
for ( j = 0; j < 100; j++) {
...
break outermost;
}
}
outermost:
statements;
For In Iterator
The following form is useful for iterating through collections:
for( property in some_collection)
{
}
This iterator iterates over all of the properties of a collection, executing the body of the iterator once for each property. The iterator body will not be executed, if the object is null or is undefined.
Example:
for (token in ['red', blue]) {
....
}
With Statement
An example is as follows:
with(some_object ) {
...
var finder = location;
}
The variable location is treated as a local variable, if it is not found in the block, it is treated as a property of the object and the object is searched for the property value.
with statements are not allowed in strict mode and are considered poor practice.
Functions
Functions And Method
A method belongs to an object and a method is called on an object. The object is
called the receiver.
In contrast in JavaScript, a function is an object : my_func.toStr.
Since functions are objects they can be passed to other functions and returned from
functions.
JavaScript Functions
A JavaScript function is defined as follows:
function myFunction( a, b) {
var x;
return expression;
}
A function consists of the function keyword, the function name, a list of parameters
enclosed in parentheses and a function body which is a collection of statements enclosed in braces. The keyword function is mandatory and the braces are also mandatory.
A function is called a pure function if it does not have any side effects.
A variable defined inside a function with the var keyword has it's scope confined to the function. In the previous function example, the scope of the variable x is confined to the function body.
Return Value Of A Function
A function may have the return keyword followed by an optional expression. When the
return keyword is encountered during the execution of the function, the function returns the value of the expression. If the return keyword is not followed by an expression or no return keyword is present inside the function body, the undefined value is returned.
Function Arguments
Even if a JavaScript function has a signature with three arguments, for example, it can be invoked with no arguments or with any number of arguments.
When a JavaScript function is invoked, JavaScript creates an array called arguments. The first argument passed to the function can be accessed as argument[0], the second argument as argument[1] and so on.
The number of arguments passed to the function can be determined with arguments.length.
Named arguments are only a convenience feature in JavaScript since the arguments array can be used instead.
We can change an array element (such as arguments[3]), this will automatically change the corresponding named argument.
The converse is not true. If we change the named
argument inside the function body then the corresponding argument array element is not changed.
In strict mode, an error occurs if an attempt is made to change an argument element.
Overloading Functions
In Javascript, function names cannot be overloaded since there are no function signatures per se. If the same function name is defined twice then Javascript will always use the last defined function.
Variable Scope And Closure
The parameters passed to a function are available as variables inside the function body:
function add(x, y)
{
return (x + y);
}
Variables that are defined inside a function body (with the var keyword) are only visible inside the function body.
function mult(x)
{
var y = 3;
return (x*y);
}
If a function does not find a required variable inside it's body, it looks for the variable in the enclosing scope:
var
y = 7;
function add(x)
{
return (x + y);
}
In this example, since y does not exist in the function's body it is picked up from the enclosing scope. In effect, all variables defined above a function's definition are visible.
A function can define another function inside it's body:
function
parent(x) {
var y = 3;
function child()
{
return x*y;
}
child();
# call the child function
}
The child function is defined inside parent(). The enclosing scope for child() is the body of the parent function. The variables x and y are visible inside child.
Lexical Scope
The scope rules in JavaScript are called lexical scoping.
JavaScript is not a block scoped language. Code inside braces { ... } does not create a new scope. The only thing that creates a new scope is a function.
Functions Returning Functions
A function can return a function. Consider this:
function parent(x) {
var y = 5;
function child(z)
{
return x*y*z;
}
return child;
//return the child function
}
var childfunc = parent(11);
childfunc(10);
//call the child function
The important point to understand is that the variables x and y in the enclosing scope of child() still exist whenever childfunc() is called. These context variables are maintained in a scope object. This is an example of closure.
Anonymous Functions
A conventional function declaration has the form:
function bank_account() {
}
When a function is defined, it is not necessary to follow the function keyword with the name of the function:
var add = function(a, b) {
return a + b;
};
The right-hand side is called a function expression. A function expression is also called an anonymous function. The function is assigned to the variable add. add is a reference to a function.
We can execute the anonymous function as follows:
add(5, 5);
Variables, Scope And Memory
In JavaScript, a variable holds a primitive value or a reference. The primitive values are: Null, Undefined, Boolean, Number and String. A reference refers to an object.
Note: objects can have properties and methods attached to them at run-time. Primitive values cannot have properties and methods attached to them at run-time.
Copying Variables
In Javascript when a primitive variable is assigned to another variable for example, x = y, the variable x is allocated new memory on the heap and then the new memory location is initialized with the value of y. This is called pass by value. However if y is an object then the assignment initializes x to point to the same location on memory as the object y. This is called pass by reference.
Function Arguments
Function arguments are passed by value. However for objects, the function receives a
reference to the object (that is, a pointer to the object on the heap).
Determining Type
The typeof operator is used to determine the type of a variable. The usage is:
typeof some_variable
This will return the type of the variable as a string:
“null”, “undefined”, “boolean” “number” or “string”. If the variable is an object then typeof will return object.
For an object the instanceOf operator can be used to determine the type of an object:
some_variable instanceOf(ObjectType)
instanceOf will return true or false.
Block Level Scopes
A block of code is a number of JavaScript statements that are enclosed in braces. JavaScript does not have block level scope. This means that variables defined inside a block of code can be accessed outside the block.
In JavaScript there are only two types of scopes. The global scope and function scope.
Variables In Functions
A variable declared inside a function has local scope if it is declared with the var keyword. If the variable is declared without the var keyword it has global scope.
Nested Scopes
Scopes can be nested:
var color = blue
function func1() {
var color2 = “red”;
func2() {
myColor = color;
}
}
There are three scopes here: the global scope where the variable color is defined, The func1
function scope and the func2 function scope. When func2 looks for the variable color, it first searches it's scope. If the variable is not found, it searches the enclosing scope func1 and then continues searching outward to the global scope. Once the variable is found in an enclosing scope the search terminates.
Objects
In JavaScript an object is an unordered collection of property value pairs. A value can be a primitive type, an object or a function. The property name can be a string or a number.
Creating JavaScript Objects
There are two ways to create a JavaScript Object.
The Object Constructor Method
A JavaScript object can be created by creating a blank object with Object.new and then adding properties to the empty object:
person = Object.new;
person.name = “jannat singh”;
person.age = 16;
person.speak = function() {
alert(this.name);
};
new is an object constructor. Instead of Object.new we can also write:
person = new Object();
Object Literal Method
The second technique for constructing an object is with object literal notation:
person =
{
name: “jannat singh”,
age: 16,
speak: function() {
alert(this.name),
};
}
An empty object can be created with : var obj = Object.new or with this symbolic
notation:
person = {};
Notice that in the object literal definition of person we have a speak property those value is a function. person.speak will execute the function.
Inside the function, the other properties of the object can be referenced as this.property.
hasOwnProperty
Every object has a hasOwnProperty method. This method determines if a object has a
certain property:
person.hasOwnProperty(“age”);
person.hasOwnProperty(“address”);
// true
// false
Object Creation Patterns: The Factory Pattern
The object creation techniques described above are cumbersome when a lot of objects have to be created. The factory pattern solves this problem. The solution is to specify a function which creates an object based on the properties passed to the function:
function createPerson(name, age)
var obj = new Object;
obj.name = name;
obj.age = age;
var sayName = function() {
return this.name
};
return obj;
};
The function createPerson can create multiple objects of the same type.
Object Creation : The Constructor Pattern
The problem with the factory pattern is that each object created is the same type of Object. JavaScript natively supports a few object types such as: Object and Array. But we may want to create objects of a custom type. The constructor Pattern lets us create such custom objects.
Consider the following function:
function Person(name, age) {
this.name = name;
this.age = age;
this.say = function sayName() {
return this.name;
};
};
The function Person actually defines a new data type (like String, Number, Object etc.) called Person.
We can now create a new object of type Person as follows:
jannat = new Person(“jannat singh”, 16);
This will create an object called jannat of type Person. If we do typeof jannat the return value will be Person.
The operation of the pattern is as follows:
When the new keyword is encountered,JavaScript creates a new empty object. JavaScript next sets this to point to the memory location of the new object. Next, JavaScript executes the function and then returns this. The this value is assigned to the the left hand side – jannat. This pattern above creates anew object of type Person.
By convention, the function name is in proper case. Inside the function body, this is replaced by the reference to the new object.
The function must not have a return statement.
Notice that the constructor defines a property say which has a function as a value.
Each object has a method called constructor which returns the type of the object. Thus:
jannat.constructor === Person; // true
The main problem with the constructor pattern is that a new memory allocation is required for each function in the object when the constructor is invoked.
Public And Private Variables
By default all of the properties of an object are public (they can be accessed with the notation object.property or object[“property”]. A private variable cannot be accessed from outside the object. We declare a private variable with:
var myObject = {
var color: blue;
}
This declares color to be a private variable of the object.
We can define an accessor function for the object which returns the private variable:
myObject.getColor = function() {
return this.color;
}
Similarly a method in an object can be declared to be private with the var keyword:
var myObject = {
var balance: function() {
7500;
};
}
Store By Value And Store By Reference
In Javascript, primitive values are stored by value. However objects are stored by
reference. For example:
var new_person = person;
If person.name is changed then new_person.name will reflect the new value. This is
because new_person is a reference to the person object.
Property Attributes
Each property in an object which has a primitive value (null, boolean, number, string, undefined) has three additional properties: configurable, enumerable and writable. The configurable attribute determines whether the property can be deleted or changed. The enumerable attribute determines whether the property is returned in a for-in loop. The writable property determines whether the property can be written to. By default all of these properties is set to true.
Accessing The Properties of An Object
There are two ways to access the value of a property on an object: the dot operator notation and the array notation:
var jannat = {
name: 'jannat',
age: 22
school: “UofT”
}
The name property can be accessed as: jannat.name or as jannat[“name”]
The array notation must be used when the property does not follow Javascript naming
conventions. An advantage of the [] notation is that the brackets can enclose a variable:
var tag = “name”;
jannat[tag] // jannat
Trying to read an undefined property will return undefined.
If a property name does not follow Javascript conventions then it must be enclosed in quotations and the array notation must be used:
myObject[“5”] = “a number'
myObject[“my color”] = 'blue'
Changing An Object's Property Value
The dot operator and the array notation can be used to change the value of a property:
myObject.street= 'Katepwa'
myObject['street'] = 'Katepwa'
If the property does not exist in the object, the assignment will create it.
Deleting A Property
A property is deleted as follows:
delete myObject.name
delete myObject['name']
Expressions In Objects
The object inside the array operator can be an expression. JavaScript will convert it to a string before doing the property operation:
myObject[3+5] will be converted to myObject[“5”]
Object Equality
Consider the object: object1 = { key: 15 }
object1 is actually a pointer to a block in memory.
When we assign object1 to a new object:
object2 = object1 then object2 points to the same location is memory. Furthermore:
object2 === object1
// true
If we change object1 as follows: object1.key = 25
then: object2.key = 25
Consider: object3 = {key: 25}; then: object3 == object1 // false
JavaScript's == operator will return true only if both objects point to the same location in memory.
Iterating Over Object Properties
The for in operator can be used to iterate over all of the enumerable properties of an object :
for (prop in my_object) {
console.log(my_object[prop])
}
This prints out the values of all the properties of the object. The property names of the object can be printed out with:
Getting The Properties Of An Object
for (prop in my_object) {
console.log(prop)
}
Prototype
The following is a constructor for an object of type Person:
function Person() {
this.name: 'jannat
this.address: 'echo lake'
};
The uppercase on Person is just a convention. We can just as well use the lower case person. The object Person is called a constructor. The constructor syntax to create a new person object is: new Person().
All constructors have a property called prototype. The value of the prototype property is an object.
We can set properties of this prototype object of Person as follows:
Person.prototype.name
= “jannat”
Person.prototype.address = “echo lake”
Person.prototype.sayName = function() {
alert(this.name);
};
Note that the prototype property Person.prototype.sayName is a property whose value is a function.
We can also create and set the properties of the prototype of the Person constructor
immediately as:
function Person(name, address) {
this.age = 25
this.country = 'Mars”
this.prototype.name = “jannat”
this.prototype.address = “echo lake”
this.prototype.sayName = function() {
alert(this.name);
};
};
We can create a new Person object as follows:
var person = new Person();
The importance of the prototype object is that all of the properties defined on the prototype object are available to existing Person objects and any other new Person objects which are created.
Additionally, properties of the prototype object are shared by the instances of Person that are created (this conserves memory).
Default Prototype Method
By default each prototype object has a default property called constructor. The constructor points to the function object that contains the prototype object:
Person.prototype.constructor == Person.
When a new object is created with a Person constructor, the created instance maintains a pointer to the prototype constructor's value. This pointer can be referenced prototype
Alternate Prototype Syntax
We can specify the prototype object for Person in literal notation:
function Person() {
Person.prototype = {
name: 'jannat',
age: 22,
sayName: function() {
alert(this.name);
}
}
When this is done, the Person.protoype.constructor points to the prototype object and not to Person. We can explicitly set the constructor as follows:
function Person()
Person.prototype = {
constructor: Person
name: 'jannat',
age: 22,
sayName: function() {
alert(this.name);
}
}
Inheritance With Prototype
JavaScript has prototype inheritance. The object that we inherit from is called a prototype.
Consider the following Animal object:
function Animal(name, numLegs) {
this.name = name;
this.numLegs = numLegs
sayName = function() {
console.log(this.name);
}
Next we construct a Penguin class.
function Penguin(name) {
this.name = name;
this.numLegs = 2;
}
Penguins are a type of Animal and thus should inherit all of the properties of the Animal Class. This is accomplished as follows:
Penguin.prototype = new Animal();
Now the Penguin class inherits all of the properties of the Animal class. The following makes use of the inherited sayName property:
penguin = new Penguin(“linux”)
penguin.sayName();
Suppose we next define a Emperor Penguin class:
function Emperor(habitat) {
this.habitat = habitat;
}
Create an instance of an Emperor penguin:
var emperor = new Emperor(“alaska”);
Next we ensure that emporer penguins inherit from penguins:
Emperor.prototype = new Penguin();
Since Emperor inherits from Penguin and Penguin inherits from Animal; Javascript will search up the inheritance tree looking for example the sayName function. The root of the class hierarchy is Object.
isPrototypeOf
IsPrototypeOf can be used to test whether a given prototype is a prototype of a certain instance object:
Person.prototype.isPrototypeOf(Animal)
getPrototypeOf()
The getPrototypeOf() function can be used to retrieve the prototype of a particular object instance:
Object.getPrototypeOf(person)
// Person.prototype
Prototypes, Accessors And Mutators
A property of a particular object instance can be retrieved as follows:
person1.name // “jannat”
Here the person1 object has retrieved the name property from the object's prototype. The person1 object contains a pointer to the prototype.
The person1 object can change the value of name as follows:
person1.name = “kaur”
The effect of this is as follows: the name property is added to the person1 instance. The value of prototype property name is not changed.
Now the accessor person1.name fetches 'kaur'. The search for a particular property or function starts with the object instance and proceeds upwards to the prototype object.
We can delete the person1 name property:
delete person1.name
Now the accessor person1.name gets the value from the prototype since the person1 object instance does not have the property name.
Prototypes And The In Operator
Objects have own properties and inherited properties. Own properties are properties which are defined by the user on the created object. Inherited properties are properties which are inherited from the object's prototype.
The in operator returns true if a property or it's prototype has the named property.
Consider:
function Person(name, address) {
this.prototype.name = “jannat”
this.prototype.address = “echo lake”
this.sayName = function() {
alert(this.name);
};
};
and
jannatkaur = new Person
Now name in jannatkaur returns true since the name property is in the prototype.
However:
jannat.hasOwnProperty(name) returns false since name is found in the prototype but notin the jannat object.
If we specify jannatkaur.name = 'jyot' then name becomes a property of the jannatkaur object and jannatkaur.hasOwnProperty('jannat') returns true. name is still a property of jannat. Note that : name in jannatkaur is also true.
Prototypes And The for-in Loop
The for-in loop has the form:
for (var prop in jannat) {
}
This will loop through all of the properties of the jannat object which are enumerable and either in the jannat object or it's prototype. By default all properties created by the user on the jannat object are enumerable.
Getting The List Of Enumerable Properties
Consider:
function Person(name, address) {
this.prototype.name = “bugga”
this.prototype.address = “echo lake”
this.sayName = function() {
alert(this.name);
};
};
and:
jannat = new Person
jannat.name = “jannat”
jannat.age = 22
The Object.keys method returns the enumerable properties of an object as an array of
strings:
var
proplist = Object.keys(Person.prototype)
This returns the array : ['name', 'age', 'sayName']
var proplist = Object.keys(jannat)
This returns only the properties on the jannat object which are not on the prototype: ['name','age']
Arrays
An array is an ordered list of properties which are numerically indexed. The index starts at zero. JavaScript arrays can grow dynamically. The index elements need not be contiguous; arrays in which the indexes are not contiguous are called sparse arrays.
Array elements need not be of the same type and array elements can be arrays as well as objects.
Creating Arrays With Array Literals
The easiest way to create an array is with array literal notation:
The empty array is created as follows:
var myArray = []
With array literal notation, arrays can be created and initialized in one step as follows:
var myArray = [“mail1”, 5, “mail3” ]
All arrays are integer indexed with the index starting at 0.
Look at this array: var myArray = [ 5, ,100]
Here, the value of myArray[0] is 5 and myArray[1] is undefined.
Creating Arrays With Constructors
The constructor notation is:
var myArray = new Array();
This creates an empty array.
var myArray = new Array('jannat', “singh', 20)
Creates an array with 3 elements.
The notation var myArray = new Array(10) simply pre-allocates space for a ten element array.
Arrays And JavaScript Objects
All arrays are JavaScript objects.
Reading And Writing Array Values
The bracket operator [] is used to read and write arrays:
var myArray = [5, 0, 1, 2, 3]; //// initialize a five element array
myArray[1] = -1;
myArray[0] = 0;
Sparse Arrays
These are arrays where the index values are not contiguous. Thus the length of the array will be greater than the number of elements. The length of an array is the largest index value plus 1.
var myArray = []
myArray[1000] = -1
// array length is 1001
We can test whether a sparse array has a value at index value i as follows:
i in mArray
Length Of An Array
All arrays have a length property. This is the only property that distinguishes them from ordinary objects. For non-sparse arrays, the length is the number of elements in the array.For a sparse array the length is the largest index value plus one.
Consider the five element array: myArray = [0,1,2,3,4]
myArray.length = 5
Now if we set the array length to 2: myArray.length = 2
This will have the effect of deleting all the elements those index is greater than or equal to the length value:
myArray.length = 2;
// myArray = [0,1]
Setting myArray.length = 1000 simply allocates additional space (but does not set new index values).
Push And Pop
The prototype object for Arrays contains the push and pop methods. The push method
pushes it's argument to the end of the array. The pop method pops the last element off the array and returns it:
myArray = [1,2,3];
myArray.push(“mail5”);
var last = myArray.pop;
// [1, 2, 3, “mail5']
// last = “mail5”
Deleting Array Elements
Array elements are deleted with the delete operator:
myArray = [1,2,3]
delete myArray[1]
The effect of this is as follows. The length of the array does not change and array indexes are not shifted downward. myArray[1] now has an undefined value.
Shift
Deletes an array value at an index and shifts higher indexes by subtracting one.
Iterating Through JavaScript Arrays
The for loop is used to iterate through an array. Let mArray be some array:
for (var i = 0, i < mArray.length, i++) {
var value = mArray[i];
....
}
Iterator Methods
forEach Iterator
The foreach iterator takes a function as an argument. For each array element, the functionis invoked with three arguments, the value of the array element, the index and the array itself:
var mArray = [ 'a', 'b', 'c' ];
var sum = 0;
mArray.forEach( function(value, index, mArray) {
sum = sum + val;
}
);
If only the value of the array is required, specify the function with only one argument.
Map Iterator
The map iterator takes a function as an argument. The function receives the value of an array element and returns a value. These returned values are used by the iterator to construct a new array:
MArray = [1, 5, 10];
mArray.map(function(val) {
return val*val;
});
// [1, 25, 100]
Filter Iterator
The filter iterator returns a subset of an array. The iterator takes a function as a parameter.
The function takes the array value as an argument and returns true or false (it is a
predicate function). If the value returned is true or can be promoted to true the array element is added to the new resultant array:
MArray = [1,2, 5, 6];
mArray.filter(function(val) {
return val < 3
});
// [1,2]
every() and some() Iterators
These iterators take a predicate function as an argument. The predicate function takes a value of the array as an argument. The every() iterator returns true only if the predicate function returns true for all iterations. The any() iterator returns true only if the predicate function returns true for at least one iterator value:
mArray = [1,2,5, 10];
mArray.every(function(val) {
val < 6;
});
// returns false
Reduce Iterator
The reduce iterator operates upon an array and reduces the array to a single value:
mArray = [1,2,3,4]
mArray.reduce(function(init, array_value, index, array) {
}, init_val);
The reduce function takes two values: a function and an optional initial value. The
function takes an initial value, array value, an optional index value and the array optionally.
On the first call to the reduce function, the initial value (init_val) is passed as the first parameter to the reduce function. The function returns an accumulating value.
For subsequent iterations, the function receives this accumulating value. In the final iteration, the final accumulated value is returned.
If the second parameter to the reduce function is not specified then the function parameter of reduce uses the first two values of the array on the initial iteration.
Multi-Dimensional Arrays
JavaScript does not support multi-dimensional arrays with a notation such as:
mArray[][]
Testing For An Array
The predicate function isArray tests whether a variable is an array:
Array.isArray(mArray);
// true or false
Join
The join method creates a string from the array elements by concatenating all of the
elements of the array. The elements are separated by the parameter passed to join:
MyArray.join(“,”)
If no parameter is passed, space is used as the string separator.
Split
The split method is the opposite of the join method. It creates an array by splitting a string. The string is split with the character which is passed to the method:
sentence.split(“ “)
Searching Arrays and indexOf
indexOf searches an array for the first occurrence of a value and if found, returns the index at which the value is located. If the value is not found then -1 is returned.
Strings And Arrays
In Javascript, strings are immutable arrays and thus string elements can be accessed with the [] operator.
var str = “hello world”;
str[4] // o
Date Objects
A date object can be instantiated as follows:
var dateObject = new Date(year, month, day)
A date object can also be instantiated as follows:
var dateObject = new Date(year, month, day, hours, minutes, seconds)
The last three arguments are optional and are zero if not specified.
If all arguments are omitted, the date object will be initialized with today's date and time.
Internally, the date object represents date and time in epoch time in milliseconds (since 1970 midnight).
The accessor methods are: getFullYear(), getMonth(), getDay(), getDate(), getHours(),getMinutes() and getSeconds().
All of these methods have setter methods except for getDay().
Dates can be compared with <, <= , >, >=.== does not work.
The timezone offset for a date object can be retrieved with: getTimeZoneOffset().
Javascript Error Handling
Exceptions are thrown by the underlying system when a critical error occurs – for example a disk that is to be written to is full or a network connection is not available. An exception can also be thrown by a software application. In Javascript, an exception can be thrown with the throw statement:
throw “network error”;
Errors can also be thrown by creating a new object to be thrown:
throw new myErrorObject(“message string”);
When an exception occurs, Javascript raises an error object. The content of the error object can typically be checked with the message method. The exception travels upwards to the root of the application and if it is not captured and handled, the application typically crashes.
Exceptions are trapped and handled in try and catch blocks:
try {
}
catch (error) {
print error.message
}
finally {
}
The statements inside the try block are executed. If an exception is thrown then it is trapped and handled in the catch block.
A try catch block can end optionally with a finally block. The finally block is executed regardless of whether an exception occurs.
Advanced JavaScript Functions
In JavaScript a function has the canonical form:
function myFunction(a, b, c)
{
}
A function is defined with the keyword: function. The function body is within the curly braces. The values between the parentheses are the arguments of the function.
Javascript functions can be assigned to variables and consequently passed as function parameters and returned by functions.
A function can be assigned as a property of an object:
var obj = new Object;
obj.speak = function sayHello() {
alert(“hello”);
}
The function is said to be a method of the object obj.
Anonymous Functions And Function Literals
The function name is not mandatory. The function name can be missing in a function
definition. For example:
var func = function(a,b) {
return a+b;
}
Here a function literal or anonymous function has been defined and assigned to a variable func.
Nested Functions
In Javascript a function can be defined inside another function and then invoked by the enclosing function:
function adder(x, y) {
function subtractor(a,b) {
return a-b;
}
z = subtractor(x, y);
return ( z + x + y);
}
The function subtractor is defined inside the adder function and then invoked in the body of adder.
The scoping rules of Javascript enables the subtractor function to read and write the variables in the body of the enclosing function as well as the parameters of adder.
Invoking JavaScript Functions
JavaScript functions can be invoked as:
(i) functions
(ii) methods
(iii) as constructors
(iv) with call and apply
Function Invocation
A Javascript function is called as: myFunction(a,b). The parameters a and b can be expressions.
Returning From A Function
A function returns when it encounters a return statement. The expression attached to the return keyword will be returned. If the function does not contain the return keyword or if a value is not attached to a return statement then undefined is returned by the function.
Method Invocation
If a function myFunc(a,b) is a property of an object obj then it is invoked as:
obj.myFunc(a,b). Instead of the dot notation, the bracket notation can be used:
obj“myFunc”
For methods, the keyword this refers to the object of which the function is a property. The object (this) is the invocation context of the method and all of the properties of the object are available to the method.
Important: Nested functions do not inherit the this context of their containing method. If the nested function is invoked as a method then it's this is the object which it is invoked on.If the nested function is invoked as a function then it does not have a this context.
Constructor Invocation
When a function is preceded with the new keyword then a new object including it's
prototype object is created:
var obj = new function adder(x, y) {
x+y;
If the function does not include parameters, we can say:
var sum = new adder
A constructor must not include the return keyword.
Function Parameters
JavaScript does not count the number of parameters passed or the type of the parameters.
When a JavaScript function is invoked with fewer parameters than in the function
parameter list, the additional parameters are set to undefined.
Varargs Functions
A varargs function is a function that can accept a variable number of parameters. The parameters passed to such a function can be retrieved from the arguments array. The first parameter passed to the function is arguments[0] and the nth argument received by the function is arguments[n-1].
The number of arguments passed to the function is arguments.length.
Assigning Functions
In Javascript, an anonymous function can be assigned to a variable. Consider the adder function:
function adder(x, y) {
return x+y;
}
We assign the function to a variable sigma:
var sigma = adder
Which assigns the function adder to the variable sigma. We can now invoke the function as:
sigma(5,6)
Functions can be defined as object properties:
obj.sigma = function(x, y) { return x+y; }
Notice that we have not defined the function name. This is a function literal.
Variable Scope
Javascript does not have the concept of block scope. In Javascript, variables have function scope. Variables inside a function are not visible outside the function if they are defined with the var keyword. But these variables are visible to any nested functions. Variables outside any function are always global variables.
Note: variables inside a function body which are declared without the var keyword have global scope.
The Scope Chain
When a function is defined, Javascript creates a scope object for the function which
contains all of the variables in the function's body and the function parameters. JavaScript then looks at the function enclosing the first function and creates another scope object for the first function consisting of the variables in the enclosing function's body and it's parameters.
This process continues until all enveloping functions have been accounted for. JavaScript then creates a scope object for the function consisting of all of the global variables.
Notice that the scope of a function is determined when it is defined. Not when it is called.This way of constructing the scope of a function is called lexical scoping.
When JavaScript has to resolve the value of a variable, it first looks for the variable in the function body and the function's parameters. If the variable is not found in this scope, it examines the variable in the enclosing scope object. This process continues until the variable is resolved or until the global scope is reached (the variables which are outside any function). If the variable is not resolved, an exception is thrown.
Closures
From the above, it is clear that a JavaScript function not only includes the code in the function body, but also the scope chain for the function. Due to lexical scoping, this scope chain is determined when the function is defined.
The combination of the function code and the scope chain is called a closure. In brief, the closure includes all variables in the function's body, it's parameters as well as variables outside the function which are in the function's scope chain.
Look at this example of a closure:
var scope = “global”,
function checkScope() {
var scope = “local”;
function f () {
return scope;
}
return f();
}
checkscope();
Here the return statement executes the nested function f and returns it's value. Due to lexical scoping rules, this value is “local”.
Now consider the following example:
var scope = “global”,
function checkScope() {
var scope = “local”;
function f () {
return scope;
}
return f;
}
checkscope()();
In this example, checkscope returns the function f. f is then executed (checkscope()() ).Due to the lexical scoping rule, checkscope()() returns “local”. checkscope()() searches its scope chain which is fixed when the function was declared.
Note the stack operation of f. After checkscope is executed, the function checkScope hasexited so all of the variables in the function's body have been taken off the stack. However f's scope chain consists of objects on the heap and any such object will not be deleted until all references to it have gone.
Consider the following function:
function adder() {
var x = 1;
return {
sum: sum() { return ++x; }
reset: reset() { return (x = 1) ;
}
}
adder returns an object. Now call adder:
var a = adder();
var b = adder();
Consider :
a.sum
//2
b.sum
//2 not 3
a.reset
//0
b.sum
//4
Here each invocation of adder() has created a new scope chain and the variable x in each scope chain is private to that scope chain.
Closures And this
Every method has a this value. It is the receiver object. A function (which is not bound to an object explicitly) has a this value set to the global object. A nested function cannot access the this value of it's outer function unless the this value is assigned to a variable.
Call And Apply
Every JavaScript function is an object and has the properties: call and apply. call and apply take a JavaScript object as an argument. Let f be a function and m an object:
f.call(m)
This has the effect of implicitly making f a property of the object m and then invoking f: that is:
f.call(m) is equivalent to m.f
Note that call changes the scope chain of the function. The scope chain starts with the object m. Furthermore all of the properties of m become accessible to f.
Call can take an optional number of arguments after the object parameter. These arguments will be the arguments of f:
f.call(m, x, y) is equivalent to m.f(x, y)
apply is identical to call expect that the arguments are placed in an array. Thus apply has an object argument and an optional array of arguments.
The bind() Function
Let o be an object and f a function. We bind f to o as follows:
var g = f.bind(o)
This makes g a method of o and sets the this value of g to the object o. Invoking g with parameters, invokes f with these parameters where f has the context of the object o.
Partial Application (Or Currying)
Consider the following situation:
var f = function(x, y, z) { return (x + y + z) }
var g = f.bind(o, 1)
Now the scope chain of g starts with the object o. The parameter 1 is bound to the
parameter x of the function f. We can call g as follows:
g( 2, 3) this is equivalent to the call : f(1, 2, 3)
Functional Programming : Higher Order Functions
A higher order function is a function that takes one or more functions as arguments and returns a function. Ordinary functions are first order functions. Functional programming is concerned with manipulating higher order functions.
Traditionally in a higher order function, the function arguments are written first.
This is an example of a function which takes an anonymous function action as a parameter:
function forEach(array, action) {
for (var i = 0; i < array.length; i++)
action(array[i]);
}
// action is some arbitrary function
function sum(numbers) {
var total = 0;
forEach(numbers, function (number) {
total += number;
});
return total;
}
show(sum([1, 10, 100]));
In the example above, for each is passed an anonymous function that updates total which is a variable within the scope of the function sum.
Function Context Binding In JavaScript
The this or self construct in languages provides a context for variables or methods. This context defines the scope of the variable or method. That is, the context or scope determines what is visible to a method or variable.
In most languages the context of a variable or method is determined at the time the variable or method is declared. Thus for example, in Ruby self always refers to the object containing the variable or method. This is not the case with JavaScript. In particular, JavaScript provides a bind function which lets us define the context of an object's variable or method at runtime. JavaScript thus provides for late binding.
In JavaScript there are four patterns for invoking functions:
• Function invocation pattern
• Method invocation pattern
• Constructor invocation pattern
• Apply invocation pattern
Each of these patterns has a different context.
Consider the ordinary function call:
var p = 90
var func = function(x) {
// ...
};
func(p)
The context (this) for this function call is the global environment or window in a browser.
Now consider an object with a function:
var unicorns = {
func: function(x) { // ... }
};
var fun = unicorns.func;
fun(x)
Here unicorns.func(z) has the object as it's context, but the variable fun has the global environment as it's context. This example shows that function context depends on how thefunction is called.
The Method Invocation Pattern
Looking at the previous pattern, the context for the method call unicorns.func is the object unicorns.
The Constructor Invocation Pattern
Consider the following constructor:
function Wizard() {
this.castSpell = function() { return "KABOOM"; };
}
var merlin = new Wizard(); // this is set to an empty object {}. Returns `this`
implicitly.
merlin.castSpell() // returns "KABOOM";
The call new Wizard returns this implicitly. merlin points to the newly created empty object. The context is the newly object.
The Apply Invocation Pattern
We can also provide a context for a function call with the apply and call functions. apply and call supply a context to the function being called. The patterns for these invocations are as follows:
call - it takes a context as the first argument. The rest of arguments are
arguments passed to the function being called this way.
apply - it takes a context as the first argument and an array of arguments for
the function being called as the second argument.
See this example:
function addAndSetX(a, b) {
this.x += a + b;
}
var obj1 = { x: 1, y: 2 };
// this = obj1, obj1 after call = { x: 3, y : 2
addAndSetX.call(obj1, 1, 1);
// It is the same as:
// addAndSetX.apply(obj1, [1, 1]);
Binding Functions
A bounded function in JavaScript is a function that is bound to a given context. That means no matter how you call it, the context of the call will stay the same. The only exception is the new operator which always return a context to the newly created object.
To create a bounded function out of a regular function, the bind method is used. The bind method takes a context to which you want to bind your function as a first argument. The rest of the arguments are any arguments that will be always be passed to such a function. The bind method returns a bounded function.
Example:
function add(x, y) {
this.result += x + y;
}
var computation1 = { result: 0 };
var boundedAdd = add.bind(computation1);
// the context `this` is set to the object `computation1`
// computation1 after the call to the bounded function: { result: 3 }
// result refers to the result in the context
boundedAdd(1, 2);
// always pass a 2 to the bounded function
var boundedAddPlusTwo = add.bind(computation1, 2);
boundedAddPlusTwo(4);
The context of a bound function cannot be changed by using call or apply on the function.
JavaScript In Browsers
The Window Object
The window object refers to the browser window or frame. It is referred to simply as
window. The window object is a global object for client-side Javascript programs. It is at the top of the scope chain. It has various properties that can be referred to without the qualifier window.
The window object also has a number of important methods such as: alert(), setTimeout(),etc.
The window Property
Each window object has the window property which refers to the window object itself.
The window Timer Property
window.setTimeout() registers a function that is invoked after a given amount of time has elapsed:
setTimeout(“showList”, 5000)
The showList function is invoked after 5000 milliseconds.
Here is another example:
setTimeout(function() {
location.href = '/upgrade'
}, 400);
The setInterval() function works identically, except that the function is invoked repeatedly after each time interval.
For setTimeout() and setInterval(), the HTML5 specification allows additional arguments tobe passed to the function after the first two arguments.
The Browser Location And Navigation
The window object has a location property. The value of the window location property (window.location) is a location object which has properties attached to it. window.location refers to the URL which is displayed in the browser window.
window.location.href is a string that refers to the complete URL of the page displayed in thewindow. This will populate the URL bar and execute the url (HTTP).
window.location has other properties such as: protocol, host, hostname, port, pathname,search and hash.
The assign method loads a new document in the window:
window.assign(“http://ibm.com”)
The URL can be a absolute or relative URL.
The replace() method is similar but is erases the current page from history so that the back button does not go back to the page traversed from.
assign() and replace() can take a fragment url (“#mark”). This causes the browser to scroll the page to the specified location.
location.search Property
The window.location.search property sets or returns the query portion of the URL. Assumethat the URL is www.jannat.singh.com/?name=jannat%surname=singh
Then location.search will return ?name=jannat&surname=singh.
A new URL query string can be set with:
location.search = “?name=jyoti&surname=singh”
Browsing History
The window object contains a history property (window.history). window.history is an object.
window.history.forward() and window.history.back() traverses the browsing history displaying the matching pages.
window.history.go(+-n) jumps to a page in the browser history + or – pages from the current location.
Opening And Closing Windows
A new window is opened in the browser with window.open(). open() takes four optional
arguments:
The URL to navigate to
The window name
A comma separated list of attributes of the new window (as a string):
"width=400,height=350,status=yes,resizable=yes"
Browsers can ignore this argument
A boolean which indicates whether the URL should replace the current
URL in the windows history. It is applicable only if the window is
named
window.open() returns the window object which has been created.
A window is closed with window.close(w) where w is a window object.
Scripting JavaScript
One of the most important properties of the window object is document. This refers to the document in the window which is represented in a tree like structure.
Script Tag
Javascript can be embedded in an HTML page or an external Javascript file can be
included in the a HTML page. This is done with the script tag. The script tag has the form:
<script>
</script>
We can place JavaScript statements in between the opening and closing tag.
The attribute : type=”text/javascript” need not be included in the script tag since this type is automatically assumed. For compatibility with older browsers it can be set as an attribute to the script tag.
Including External JavaScript Files
External JavaScript files are included in a HTML page with the src attribute:
<script src=”externalFile.js” ></script>
The src attribute can be a complete URL. When an external file is included, no JavaScript can be placed in between the opening and closing tags.
Newer browsers understand the self-closing tag:
<script src=”externalFile.js” />
How A HTML Page with Javascript Is Processed
The interpreter starts interpreting the page from the top. When it encounters the tag it stops until the JavaScript is interpreted and loaded into memory. Page rendering commences once the tag is encountered.
The tag can be placed anywhere in the section or the section of a HTML page. For the above reason it is preferable to place the JavaScript at the bottom of the section.
The Defer Attribute
The defer attribute is optional and can be added to the script tag. It only applies to external scripts which are to be included in the page. This attribute directs the Browser engine to download the external JavaScript file after the page has been displayed. The effect is similar to placing the script tag at the end of the section.
<script type=”text/javascript” defer>
</script>
tags with the defer attribute load in the order in which they are encountered (after the page has finished loading).
The Asych Attribute
This attribute downloads the external JavaScript file in a thread and continues processing the rest of the file in another thread.
The noscript Tag
A noscripT tag can be specified inside the body section. The tag can include any HTML. The content of the tag will be rendered if the browser does not support JavaScript or if JavaScript is turned off.
The Document Object Model
getElementById
If you want to get or change the value of a HTML element give the HTML element an id. The element can then be accessed with the getElementById method. This is a method of the document object.
Accessing And Changing A HTML Element
Suppose that we have the DOM element
<p id=”som”>hello</p>
We can access the hello element with:
var el = document.getElementById(“som”).innerHTML
We can change this element with:
document.getElementById(“som”).innerHTML = 'hello world”
Scroll To A Given ID On The Page
document.getElementById('trade-notice').scrollIntoView();
Accessing And Changing A Form Element
Suppose we have the following form:
<p type='text' id='myText' />
<input type='button' onclick='notEmpty()' value='Form Checker' />
We get a reference to the HTML element with:
ref = document.getElementById('myText');
The method takes an HTML element id as a parameter and returns a reference to the
HTML element. To get the value of the HTML form element we would do:
val = document.getElementById('myText').value;
// or ref.value
Test Whether A Checkbox Is Checked
<script type="text/javascript">
function validate() {
if (document.getElementById('remember').checked) {
alert("checked");
} else {
alert("You didn't check it! Let me check it for you.");
}
}
</script>
Accessing The Value Of A Non-Form HTML Element
Each HTML element has an innerHTML property which is the HTML tag and the text
which is between the open and close tags of the element.
Consider the following HTML:
<p id='modern'>Hello World </p>
We access the text Hello World as follows:
val = document.getElementById('modern').innerHTML;
Change The Text Of HTML Element
You can also change the text of an HTML element with the innerHTML method:
<p id=”header”>Hello </p>
The following JavaScript changes the value of the H1 tag to “BYE”.
<script type=”text/javascript”>
document.getElementById(“header”).innerHTML=”BYE”;
</script>
Get, Set Or Remove An Attribute Of An HTML Element
Suppose that we want to get the value of the src attribute of the HTML element which has ID 'image':
< img id=”image” src=”pic1.jpeg”> </img>
The following Javascript code does this:
val = document.getElementById(“image”).getAttribute('src');
getAttribute will return an empty string if the attribute does not exist.
Suppose that we want to set the attribute src. The following Javascript code accomplishes this:
document.getElementById(“image”).setAttribute('src', 'newpic.jpeg');
The attribute src can be removed as an attribute with:
document.getElementById(“image”).removeAttribute('src' );
Create A JavaScript Popup
The popup will appear inside a div or span element so create a CSS style for it:
<style type="text/css">
.popup {
position:absolute; right:0; bottom:-80;
width: 400px;
border: 1px solid black;
padding: 10px;
background: white;
font-family: Times New Roman;
font-weight: 200;
text-align: left;
z-index: -2;
visibility: hidden;
}
</style>
Note that the visibility property is hidden.
Next create two JavaScript functions to handle display:
<script type=”text/javascript”>
function ShowPop(id) {
document.getElementBy(id).style.visibility = "visible";
}
function HidePop(id)
{
document.getElementBy(Id).style.visibility = "hidden";
}
</script>
Now we will attach the popup to a link:
<td>
<a href="#;" onMouseover="ShowPop('message_div');" on
Mouseout="HidePop('message_div');" > Click Here </a>
</td>
Next create a span or div element with the id message:
<div id="message_div" class='popup'>
lorem ipsum factum ....
</div>
Get The Value Of A Label
A label is different from a form element whose value is obtained or set with the . operator notation.
<td id=”pay”>Pay No</td>
Get the value of the label id:
document.pay
Set The value of the label:
document.pay = “hello world”
Accessing Forms
A form can be accessed as follows:
document.order.payno
document is the document object. order is the id or name identifier of the form. payno is the name of the form element. The value of the element is:
document.order.payno.value
Get The Value Of A Form Checkbox
if (document.getElementById('atr60DefaultColor').checked) {
pref.atr60DefaultColor = 1;
}
else {
pref.atr60DefaultColor = 0;
}
Set The Value Of A Checkbox
document.getElementById(“id”).checked = [ true | false]
Get The Value Of A Form Text Box
Create the JavaScript function:
<script type =”text/javascript”>
function get_text_value() {
var txt = document.getElementById('txt_element');
// view the value of the test element
alert(txt.value);
}
</script>
The HTML Fragment is:
<tr onMouseout="get_text_value();">
<td>
<%= f.text_field 'bill_name', :id => 'bill_name' %>
</td>
</tr>
Set The Value Of A Text
Create the javaScript function:
function set_value() {
var val1 = document.getElementById('valA');
var val2 = document.getElementById('valB');
val1.value = val2.value;
}
You can also do this:
id_box = Document.getElementById(“ida”)
id_box.value = “hello”
Get The Selected Value Of A Dropdown Box, Set The Selected Value In Another
Dropdown Box
Create the JavaScript Function
function dropdown-box_selector()
{
var dropdown_box_1 = document.getElementById('dropdownbox');
// get the selected index
var selIndex = dropdown_box_1.selectedIndex;
// Get The Selected Value
var selValue = dropdown_box_1.options[selIndex].value;
// Identify another dropdown box
var dropdown_box_2 = document.getElementById('another_dropdown');
// Set it's selected index value to the same value as the first dropdown box
dropdown_box_2.options[selIndex].selected = true;
}
This is the corresponding HTML fragment:
<td onblur=”dropdownbox_selector;”>
<%= f.select 'ship_state_prov', state_options,:id => 'dropdownbox' , %>
</td>
Hide Or Show An Element
Show or hide a particular HTML element:
document.getElementById('for_delivery').style.visibility = 'hidden';
document.getElementById('for_delivery').style.visibility = 'visible';
document.getElementById('for_delivery').style.display = 'inline';
Javascript Back Button
The following creates a Javascript enabled back button which goes back to the previous page:
<a href=”#” onClick=”history.go(-1)”>Back</a>
<input type=button value=”Back” onClick=”history.go(-1)”>
The -1 can be replaced with -n to traverse back n pages.
Time And Date Arithmetic
Epoch time now:
var now = (new Date).getTime()/1000;
ES6 Syntax
Prior to ES6, the only way to declare a variable was with the var keyword. There are now several ways to declare variables.
const keyword
A constant is a variable that cannot be changed. After the variable is declared and
assigned a value, it cannot be mutated. An attempt to change it will throw an exception.
const pizza = true
pizza = false
//exception thrown
let keyword
In JavaScript, curly braces delimit blocks of code. Until ES6, a variable defined inside a block was visible outside a block, providing the curly braces were not part of a function definition.
In ES6 a variable can be defined to only have visibility in a block of code by defining the variable with the let keyword:
var topic = "JavaScript"
if (topic) {
let topic = "React"
// React
console.log('block', topic)
}
console.log('global', topic) // Javascript
Template Strings
ES6 enables string interpolation using the ${variable} syntax:
console.log(`${lastName}, ${firstName} ${middleName}`)
The Javascript interpreter will substitute the value of the variables firstName, lastName and middleName into the string.
Notice that backticks are used instead of quotation marks to delimit the string.
The interpolation of expressions inside strings is supported:
var str = `JavaScript first appeared ${a+b} years ago. Crazy!`
Functions can also be called:
function fn() { return "I am a result. Rarr"; }
var str = `foo ${fn()} bar`
ES6 style strings honour spacing and line returns. This permits multi-line strings to be written naturally:
var x =
`Hello ${firstName},
Thanks for ordering ${qty} tickets to ${event}.
Order Details
${firstName} ${middleName} ${lastName}
${qty} x $${price} = $${qty*price} to ${event}
You can pick your tickets up at will call 30 minutes before
the show.
Thanks,
${ticketAgent}`
Function Default Parameters
Default parameters are included in the ES6 spec. This means that if a function is called without providing a value for an argument, then the default value will be used.
function logActivity(name="p.singh", activity="cs") {
console.log( `${name} loves ${activity}` )
}
If logActivity is called with: logActivity(“jannat”), then the function will use “cs” as the value for activity.
Arrow Functions
Arrow functions shorten the syntax for anonymous functions. With arrow functions, you can create functions without using the function keyword. You also do not have to use the return keyword.
An anonymous function prior to ES6 has the form:
var locator = function(address) {
return `my location is ${address}`
}
console.log( locator("bc")
With arrow style functions, this can be reduced to:
var locator = (address) => `my location is ${address}`
If there is only one argument then the parentheses are not needed.
The arrow function can have more than one line in the function body by enclosing the
body in braces:
var locator = (address) => {
address = ‘’;
`my location is ${address}`;
}
Transpiling ES6
Not all web browsers support ES6, and even those that do don’t support everything. The only way to be sure that your ES6 code will work is to convert it to ES5 code before running it in the browser. This process is called transpiling. Babel is a transpiler.
Destructuring Assignments For Arrays And Objects
Destructuring is a JavaScript expression that makes it possible to extract values from arrays, or properties from objects, into distinct variables. That is, we can extract data from arrays and objects and assign them to variables.
Prior to ES6, if we wanted to extract values from an array, we would proceed as follows:
var introduction = ["Hello", "I" , "am", "jannat"];
var greeting = introduction[0];
var name = introduction[3];
console.log(greeting);
console.log(name);
//"Hello"
//"jannat”
With ES6 we can do the following:
[greet, me] = introduction
console.log(greet)
console.log(me)
// “hello”
// “I”
The variables greet and me need not be declared previously.
Suppose we only want the first and fourth elements of the array. We do:
[x,,,y] = ["Hello", "I" , "am", "jannat"]
console.log(x)
console.log(y)
// “I”
// “jannat”
We skip over unwanted array elements with the commas.
We can also assign some of the elements of an array to variables and the remainder of the array to a variable (it will be off type array).
var [greeting, ...intro] = ["Hello", "I" , "am", "jannat"];
console.log(greeting);//"Hello"
console.log(intro);//["I", "am", "jannat"]
Notice the three dots.
var sandwich = {
bread: "dutch crunch",
meat: "tuna",
cheese: "swiss",
toppings: ["lettuce", "tomato", "mustard"]
}
Prior to ES6 we would extract the values of the object bread and meat with:
sandwich.bread and sandwich.meat. With ES6 we can do this as follows:
Default Values
Default values can be assigned to the variables just in case the value extracted from the array is undefined.
var[greeting = "hi",name = "jannat"] = ["hello"];
console.log(greeting);
console.log(name);
//"Hello"
//"jannat"
Can be written with ES6 as:
({bread}) → console.log(sandwich.bread);
Destructuring Objects
In object destructuring, we want to extract data from an object and assign to new
variables.
Prior to ES6 we would do:
var person = {name: "jannat", country: "canada", job: "Developer"};
var name = person.name;
var country = person.country;
var job = person.job;
console.log(name);
//"jannat"
console.log(country);
console.log(job);
//"canada"
//Developer"
With ES6, we can do:
var person = {name: "jannat", country: "canada", job: "Developer"}
var {name, country, job} = person;
console.log(name);
console.log(country);
console.log(job);
//"jannat"
//"canada"
//Developer"
The variables in the object on the left hand side should have the same name as a property key in the object person. If the names are different, we'll get undefined.
Notice the var is required. If it is missing we will get an exception. The interpreter will think that the braces are a block of code. So if the var is absent do:
({name, country, job} = person);
If we want to assign values of a object to a new variable instead of using the name of the property, we'll do this:
var person = {name: "jannat", country: "canada", job: "Developer"}
var {name: foo, job: bar} = person;
console.log(foo);//"jannat"
console.log(bar);//"Developer"
Default values can also be used in object destructuring, just in case a variable is
undefined in an object it wants to extract data from:
var person = {name: "jannat", country: "canada", job: "Developer"}
var {name=’jannat’, friend=”annie”} = person;
console.log(name);
console.log(friend);
//"jannat"
//"annie"
var {name:foo =’jannat’, friend:bar =”annie”} = person;
console.log(foo);
console.log(bar);
//"jannat"
//"annie"
Enhanced Object Literals
With object literal enhancement we can take global variables or variables in scope and turn them into objects:
var name = "Tallac"
var elevation = 9738
// constructing an object literal the old way:
{ name: “Talloc”, elevation: 9738 }
// the ES6 way
{ name, elevation }
The JavaScript interpreter checks if the property key has a corresponding variable name and assigns the value of that variable to the property. Note if no variable has the same name as the property key defined, we'll get an exception.
Functions in objects can be written more concisely:
Prior to ES6 we would write:
{
hello: ‘hi’,
greet: function() {
return alert(hello);
}
}
In ES6 this can be written as:
{
hello: ‘hi’,
greet() {
return alert(hello);
}
}
Computed Object Literals
There are two ways to specify a key when accessing an object property: the dot notation and bracket notation. The bracket notation allows us to access a property using expressions. Computed property names allow us to write an expression wrapped in square brackets instead of the regular property name. Whatever the expression evaluates to will become the property name. This means that we can do this:
var name = "make";
const laptop = {
}
console.log(laptop.make);//"Apple"
The value of name was computed to make and this was used as the name of the
property.
We can also do:
var name = "make";
var i = 0;
const laptop = {
}
console.log(laptop.make1);//"Apple"
console.log(laptop.make2);//"Dell"
console.log(laptop.make3);//"HP"
Spread Operator
The spread operator (...some_variable) allows an expression to be inline expanded inside another expression (particularly arrays). Without the spread operator, we have:
var middle = [3, 4];
var arr = [1, 2, middle, 5, 6];
console.log(arr);
// [1, 2, [3, 4], 5, 6]
Lets use the spread operator:
var middle = [3, 4];
var arr = [1, 2, ...middle, 5, 6];
console.log(arr);
// [1, 2, 3, 4, 5, 6]
Another example:
var arr = ['a', 'b', 'c'];
var arr2 = ['d', 'e', 'f'];
arr = [...arr, ...arr2];
console.log(arr);
// ['a', 'b', 'c', 'd', 'e', 'f']
Strings To Arrays
The spread operator can be used to convert a string to an array:
var str = "hello";
var chars = [...str];
console.log(chars);
// ['h', 'e',' l',' l', 'o']
New Array Copies Not References
var arr = ['a', 'b', 'c'];
var arr2 = [...arr];
console.log(arr2);
// ['a', 'b', 'c']
arr2 is not a reference to arr.
Promises
Promises are an ES6 technique to reduce complexity in asynchronous programming.
Firstly create a promise object:
var mypromise = new Promise(function(resolve, reject) {
// asynch code block
// call resolve() if task successfully completed
if success {
resolve(phone)
}
else {
// call reject() if task has failed
reject(reason)
}
})
The promise constructor receives an anonymous callback function as an argument. This
function has two functions as arguments: a resolve function and a reject function. The body of the anonymous function is the asynchronous code that is to be run. If the result of the async task execution is successful, the resolve function is executed otherwise the reject function is executed. In either case, the parameter of the callback function is something returned by the async task.
After the async task completes the then method of the promise object is executed:
myPromise.then(
function(success) {
},
function(error) {
console.log('Error ' + error)
}
then receives two anonymous functions. if the async task succeeds, the first function inside then() is run, if it fails, the 2 nd is run instead. We can also handle errors using the catch() method instead.
The parameter received by the first function is the argument of the resolve function in the promise object. The parameter received by the second function is the argument of the reject function in the promise object.
Promises can be chained. This will occur when the success function returns a new
promise object.
Here is an example:
myPromise
.then(function (result) {
return new promise object;
})
.then(function (result) {
return another promise object;
})
.then(function (result) {
return something;
}, function (err) {
// Something in the above chain went wrong?
// Print reject output.
console.error(err);
});
JavaScript Classes
ES6 introduces classical inheritance and classes to Javascript. Classes are defined as follows:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
// Getter
getArea() {
return this.calcArea();
}
// Method
calcArea() {
return this.height * this.width;
}
}
The constructor method is a special method initializing an object created from a class.this refers to the object created from the class. The functions inside the class are called methods.
Once we have created a class, you can create a new instance of the class using the new keyword:
var rect = new Rectangle(5, 6)
This creates a new Rectangle object called rect with height 5 and width 6.
A method in the class instance rect can be called with the dot operator:
var area = rect.getArea()
Static Methods
When a class method is preceded by the static keyword, this defines a static method in the class. Static methods are called without instantiating (creating) the class in which they are defined and furthermore cannot be called through a class instance. In the following example, we define a static method and then call it.
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static distance(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.hypot(dx, dy);
}
}
console.log(Point.distance(p1, p2));
Subclasses
The extends keyword is used in class declarations or class expressions to create a class as a child of another class.
class Animal {
constructor(name, age) {
this.name = name;
this.age = age
}
getage() {
return age
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
// the age method is inherited from Animal
speak() {
console.log(this.name + ' barks.');
}
}
var d = new Dog('fido', 5);
d.speak(); // fido barks.
Super
The super keyword is used to call functions on an object's parent (super class). In the above example, Animal is the superclass of the class Dog.
class Cat {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Lion extends Cat {
speak() {
super.speak(); //speak() method in the superclass is called
console.log(this.name + ' roars.');
}
}
var l = new Lion('Fuzzy');
l.speak();
// Fuzzy makes a noise, Fuzzy roars.
ES6 Modules
A JavaScript module is a file containing variables and code. Until recently, the only way to work with modular JavaScript was to incorporate a library that could handle importing and exporting modules. Now, with ES6, JavaScript itself supports modules.
Everything in a Javascript module is private to the module unless exported.
The export keyword is used to export any JavaScript type that will be consumed in
another module.
Sometimes you may want to export only one variable from a module. In these cases you
can use export default:
const freel = new Expedition()
export default freel
Modules are consumed in other JavaScript files using the **import** statement. Modules with multiple exports can take advantage of object destructuring. Modules that use export default are imported into a single variable.
import { print, log } from './mymodulefile'
import freel from './mt-freel'
We can scope module variables locally under different variable names:
import { print as p, log as l } from './mymodulefile'
CommonJS
CommonJS is the module pattern that is supported by all versions of Node.js. You can
still use these modules with Babel and webpack. With CommonJS, JavaScript objects are exported using module.exports:
mymodulefile.js
const print(message) =>log(message, new Date())
const log(message, timestamp) =>console.log(“now”)
module.exports = { print, log}
Modules are imported with the require function:
`
const { log, print } = require ( './mymodulefile')
`
Top comments (6)
Nice job mentee! Very thorough! It would be awesome if there was a nice organized table of contents at the top so its easier to navigate. Well done though for sure, that's a huge bit of compiled info!
Thanks! Yes good idea. I'll get down to the TOC..
I'm honestly very curious to know how much time did it took you to compile all of this and even to write all this whole post and format it and stuff.
3-4 months on and off to compile (read,take notes) as I worked on other projects and read books. About a couple of hours (3 approximately) to edit and format with markdown and put up here.
It’s still a work in progress..
Damn! That's definitely impressive, hats off to you for such an awesome job done and I'm sure you'll keep making it better.
you’re welcome :)