Tuesday, August 29, 2023

JavaScript Learning in Progress

When JavaScript variables are declared, they have an initial value of undefined. If you do a mathematical operation on an undefined variable your result will be NaN which means "Not a Number". If you concatenate a string with an undefined variable, you will get a string of undefined.

MYVAR is not the same as MyVar nor myvar. It is possible to have multiple distinct variables with the same name but different casing. It is strongly recommended that for the sake of clarity, you do not use this language feature. Write variable names in JavaScript in camelCase. In camelCase, multi-word variable names have the first word in lowercase and the first letter of each subsequent word is capitalized.

Unlike var, when you use let, a variable with the same name can only be declared once.

const has all the awesome features that let has, with the added bonus that variables declared using const are read-only. They are a constant value, which means that once a variable is assigned with const, it cannot be reassigned. Note: It is common for developers to use uppercase variable identifiers for immutable values and lowercase or camelCase for mutable values (objects and arrays).

You can easily increment or add one to a variable with the ++ operator. You can easily decrement or decrease a variable by one with the -- operator.

Decimal numbers are sometimes referred to as floating point numbers or floats. Note: when you compute numbers, they are computed with finite precision. Operations using floating points may lead to different results than the desired outcome.

The remainder operator % gives the remainder of the division of two numbers. In mathematics, a number can be checked to be even or odd by checking the remainder of the division of the number by 2. Even numbers have a remainder of 0, while odd numbers a remainder of 1. Note: The remainder operator is sometimes incorrectly referred to as the modulus operator. It is very similar to modulus, but does not work properly with negative numbers.

In JavaScript, you can escape a quote from considering it as an end of string quote by placing a backslash (\) in front of the quote. This signals to JavaScript that the following quote is not the end of the string, but should instead appear inside the string.

Note that the backslash itself must be escaped in order to display as a backslash.

CodeOutput
\'single quote
\"double quote
\\backslash
\nnewline
\ttab
\rcarriage return
\bbackspace
\fform feed

Carriage return means to return to the beginning of the current line without advancing downward. The name comes from a printer's carriage, as monitors were rare when the name was coined. This is commonly escaped as "\r", abbreviated CR, and has ASCII value 13 or 0xD.

Linefeed means to advance downward to the next line; however, it has been repurposed and renamed. Used as "newline", it terminates lines (commonly confused with separating lines). This is commonly escaped as "\n", abbreviated LF or NL, and has ASCII value 10 or 0xA. CRLF (but not CRNL) is used for the pair "\r\n".

Form feed means advance downward to the next "page". It was commonly used as page separators, but now is also used as section separators. Text editors can use this character when you "insert a page break". This is commonly escaped as "\f", abbreviated FF, and has ASCII value 12 or 0xC.

\r is carriage return and moves the cursor back

printf("stackoverflow\rnine")
ninekoverflow

means it has shifted the cursor to the beginning of "stackoverflow" and overwrites the starting four characters since "nine" is four character long.

\n is new line character which changes the line and takes the cursor to the beginning of a new line like-

printf("stackoverflow\nnine")
stackoverflow
nine

\f is form feed, its use has become obsolete but it is used for giving indentation like

printf("stackoverflow\fnine")
stackoverflow
             nine

if i will write like-

printf("stackoverflow\fnine\fgreat")
stackoverflow
             nine
                 great

We can also use the += operator to concatenate a string onto the end of an existing string variable. This can be very helpful to break a long string over several lines. Note: Watch out for spaces. Concatenation does not add spaces between concatenated strings, so you'll need to add them yourself.

You can find the length of a String value by writing .length after the string variable or string literal. Note that the space character between "Alan" and "Peter" is also counted.

Bracket notation is a way to get a character at a specific index within a string. Most modern programming languages, like JavaScript, don't start counting at 1 like humans do. They start at 0. This is referred to as Zero-based indexing. In JavaScript, String values are immutable, which means that they cannot be altered once created.

 In order to get the last letter of a string, you can subtract one from the string's length.

const lastLetter = somestring[somestring.length - 1];

You can use the same principle we just used to retrieve the last character in a string to retrieve the Nth-to-last character.

For example, you can get the value of the third-to-last letter of the const firstName = "Leon" string by using firstName[firstName.length - 3]

 You start an array declaration with an opening square bracket, end it with a closing square bracket, and put a comma between each entry.

You can also nest arrays within other arrays:

const teams = [["Bulls", 23], ["White Sox", 45]];

This is also called a multi-dimensional array. One way to think of a multi-dimensional array, is as an array of arrays. When you use brackets to access your array, the first set of brackets refers to the entries in the outermost (the first level) array, and each additional pair of brackets refers to the next level of entries inside. Note: There shouldn't be any spaces between the array name and the square brackets.

Array indexes are written in the same bracket notation that strings use, except that instead of specifying a character, they are specifying an entry in the array. Like strings, arrays use zero-based indexing, so the first element in an array has an index of 0.

Unlike strings, the entries of arrays are mutable and can be changed freely, even if the array was declared with const. 

An easy way to append data to the end of an array is via the push() function. .push() takes one or more parameters and "pushes" them onto the end of the array.

 .pop() is used to pop a value off of the end of an array. We can store this popped off value by assigning it to a variable. In other words, .pop() removes the last element from an array and returns that element.

pop() always removes the last element of an array.  .shift() removes the first element.

Not only can you shift elements off of the beginning of an array, you can also unshift elements to the beginning of an array i.e. add elements in front of the array.

.unshift() works exactly like .push(), but instead of adding the element at the end of the array, unshift() adds the element at the beginning of the array.

Parameters are variables that act as placeholders for the values that are to be input to a function when it is called. When a function is defined, it is typically defined along with one or more parameters. The actual values that are input (or "passed") into a function when it is called are known as arguments.

In JavaScript, scope refers to the visibility of variables. Variables which are defined outside of a function block have Global scope. This means, they can be seen everywhere in your JavaScript code.

Variables which are declared without the let or const keywords are automatically created in the global scope. This can create unintended consequences elsewhere in your code or when running a function again. You should always declare your variables with let or const. Variables which are declared within a function, as well as the function parameters, have local scope. That means they are only visible within that function. It is possible to have both local and global variables with the same name. When you do this, the local variable takes precedence over the global variable.

A function can include the return statement but it does not have to. In the case that the function doesn't have a return statement, when you call it, the function processes the inner code but the returned value is undefined.

let sum = 0;
function addSum(num) {
  sum = sum + num;
}
addSum(3);

addSum is a function without a return statement. The function will change the global sum variable but the returned value of the function is undefined.

 The most basic operator is the equality operator ==. The equality operator compares two values and returns true if they're equivalent or false if they are not. Note that equality is different from assignment (=), which assigns the value on the right of the operator to a variable on the left.

Strict equality (===) is the counterpart to the equality operator (==). However, unlike the equality operator, which attempts to convert both values being compared to a common type, the strict equality operator does not perform a type conversion.

If the values being compared have different types, they are considered unequal, and the strict equality operator will return false.

Examples

3 ===  3  // true
3 === '3' // false

If the values being compared are not of the same type, the equality operator will perform a type conversion, and then evaluate the values. However, the strict equality operator will compare both the data type and value as-is, without converting one type to the other.

Examples

3 == '3' returns true because JavaScript performs type conversion from string to number. 3 === '3' returns false because the types are different and type conversion is not performed.

Note: In JavaScript, you can determine the type of a variable or a value with the typeof operator, as follows:

typeof 3
typeof '3'

typeof 3 returns the string number, and typeof '3' returns the string string.

The inequality operator (!=) is the opposite of the equality operator. It means not equal and returns false where equality would return true and vice versa. Like the equality operator, the inequality operator will convert data types of values while comparing.

The strict inequality operator (!==) is the logical opposite of the strict equality operator. It means "Strictly Not Equal" and returns false where strict equality would return true and vice versa. The strict inequality operator will not convert data types.

Like the equality operator, the greater than operator and the greater than or equal to operator will convert data types of values while comparing.

 Sometimes you will need to test more than one thing at a time. The logical and operator (&&) returns true if and only if the operands to the left and right of it are true.

The logical or operator (||) returns true if either of the operands is true. Otherwise, it returns false.

The logical or operator is composed of two pipe symbols: (||). This can typically be found between your Backspace and Enter keys.

 When a condition for an if statement is true, the block of code following it is executed. When that condition is false, normally nothing would happen. With an else statement, an alternate block of code can be executed.

If you have multiple conditions that need to be addressed, you can chain if statements together with else if statements. if/else statements can be chained together for complex logic.

If you need to match one value against many options, you can use a switch statement. A switch statement compares the value to the case statements which define various possible values. Any valid JavaScript statements can be executed inside a case block and will run from the first matched case value until a break is encountered. case values are tested with strict equality (===). The break tells JavaScript to stop executing statements. If the break is omitted, the next statement will be executed.

In a switch statement you may not be able to specify all possible values as case statements. Instead, you can add the default statement which will be executed if no matching case statements are found. Think of it like the final else statement in an if/else chain.

If the break statement is omitted from a switch statement's case, the following case statement(s) are executed until a break is encountered. Switch cases use strict comparison (===).

 When a return statement is reached, the execution of the current function stops and control returns to the calling location.

 Objects are similar to arrays, except that instead of using indexes to access and modify their data, you access the data in objects through what are called properties.

In this example, all the properties are stored as strings, such as name, legs, and tails. However, you can also use numbers as properties. You can even omit the quotes for single-word string properties, as follows:

const anotherObject = {
  make: "Ford",
  5: "five",
  "model": "focus"
};

However, if your object has any non-string properties, JavaScript will automatically typecast them as strings.

There are two ways to access the properties of an object: dot notation (.) and bracket notation ([]), similar to an array. Dot notation is what you use when you know the name of the property you're trying to access ahead of time.

The second way to access the properties of an object is bracket notation ([]). If the property of the object you are trying to access has a space in its name, you will need to use bracket notation. However, you can still use bracket notation on object properties without spaces. Note that property names with spaces in them must be in quotes (single or double).

Add properties to object: ourDog.bark = 'woof'; Delete properties from objects: delete ourDog.bark;

 Objects can be thought of as a key/value storage, like a dictionary. If you have tabular data, you can use an object to lookup values rather than a switch statement or an if/else chain. This is most useful when you know that your input data is limited to a certain range.

 To check if a property on a given object exists or not, you can use the .hasOwnProperty() method. someObject.hasOwnProperty(someProperty) returns true or false depending on if the property is found on the object or not.

Sometimes you may want to store data in a flexible Data Structure. A JavaScript object is one way to handle flexible data. They allow for arbitrary combinations of strings, numbers, booleans, arrays, functions, and objects.

The sub-properties of objects can be accessed by chaining together the dot or bracket notation.

For loops are declared with three optional expressions separated by semicolons:

for (a; b; c), where a is the initialization statement, b is the condition statement, and c is the final expression.

The initialization statement is executed one time only before the loop starts. It is typically used to define and setup your loop variable.

The condition statement is evaluated at the beginning of every loop iteration and will continue as long as it evaluates to true. When the condition is false at the start of the iteration, the loop will stop executing. This means if the condition starts as false, your loop will never execute.

The final expression is executed at the end of each loop iteration, prior to the next condition check and is usually used to increment or decrement your loop counter.

It is called a do...while loop because it will first do one pass of the code inside the loop no matter what, and then continue to run the loop while the specified condition evaluates to true. What makes the do...while different from other loops is how it behaves when the condition fails on the first check. Essentially, a do...while loop ensures that the code inside the loop will run at least once. Let's try getting a do...while loop to work by pushing values to an array.

JavaScript has a Math.random() function that generates a random decimal number between 0 (inclusive) and 1 (exclusive). Thus Math.random() can return a 0 but never return a 1. Note: Like Storing Values with the Assignment Operator, all function calls will be resolved before the return executes, so we can return the value of the Math.random() function. Use Math.floor() to round a number down to its nearest whole number. Math.random() can never quite return a 1.

function randomRange(myMin, myMax) {
  return Math.floor(Math.random() * (myMax - myMin + 1)) + myMin

The parseInt() function parses a string and returns an integer.

The parseInt() function parses a string and returns an integer. It takes a second argument for the radix, which specifies the base of the number in the string. The radix can be an integer between 2 and 36. The function call looks like: parseInt(string, radix); The radix variable says that string is in the binary system, or base 2.

The conditional operator, also called the ternary operator, can be used as a one line if-else expression.

The syntax is a ? b : c, where a is the condition, b is the code to run when the condition returns true, and c is the code to run when the condition returns false. One can also chain conditional (ternary) operators together to check for multiple conditions.

The following function uses if, else if, and else statements to check multiple conditions:

function findGreaterOrEqual(a, b) {
  if (a === b) {
    return "a and b are equal";
  }
  else if (a > b) {
    return "a is greater";
  }
  else {
    return "b is greater";
  }
}

The above function can be re-written using multiple conditional operators:

function findGreaterOrEqual(a, b) {
  return (a === b) ? "a and b are equal" 
    : (a > b) ? "a is greater" 
    : "b is greater";
}
It is considered best practice to format multiple conditional operators such that each condition is on a separate line, as shown above. Using multiple conditional operators without proper indentation may make your code hard to read.