Notes on JavaScript

Introduction to JavaScript

JavaScript enables us to program code that performs actions. When coding, a user can input comments to the code by placing text between /* and */. A single line comment can also be added by just preceding the line with //. This text may be useful to someone reviewing and trying to understand the code

Data Types in Javascript

Depending upon what datatype you use, Javascript will treat your text differently. Javascript has 8 basic datatypes:

Data Type Properties and Methods

Each data type possesses specific properties. These can be accessed by appending the property name after the data.

String Properties and Methods

Properties
Methods

Manipulating Data Types

To determine what type of data a variable is, typeof prior to the variable name will return the data type.
Example: console.log(typeof testVar) prints Number if testVar = 1.

Number

Numbers can be arithmetically manipulated in Javascript. The following are the syntax for operations.

Strings

Strings can be manipulated in many ways using Javascript.

Built in Objects and Commands

Console

Math

Variables

Variables allow for the storing of values within code. Several types of variables exist and are used in various scenarios.

Variables and Math

Once a variable is assigned a number value, it can be manipulated and used as that number.
Example: let w = 10. w = 1 + w. w now = 11.
Further this can be shorthanded as w += 1. This adds one to w and updates it to its new value.
This works for all math functions.

Another mathematical manipulation of variables is incrementing and decrimenting.

Variables and Strings

Variables can hold strings and the strings manipulated by concatenation. Example: Set text = 'Try me'. Then, text + ' on for size.' = 'Try me on for size.'

Variable Scope

Variables can occur in different scopes within written code. The primary scopes are:

Arrays (Lists of Information)

Arrays are lists of data (called elements), and a foundational concept of coding. Example: ['value1', 'value2', 'value3']. These can be saved to a variable.
Once an array has been saved as a variable, its values can be accessed using bracket ([]) notation, accessing a value at a specific number beginning with 0.
Example: Save an array as array = ['try', 'ask', 'again']. Then access values as array[0] = 'try'.

In this same manner then can values in an array be updated by setting values equal to the array bracket position.
Example: array[0] = 'toast' will replace 'try' with 'toast'.
This should be noted to work for arrays assigned with a let statement and not those assigned with const.

Finally, it should be noted that changes to an array established in global scope made within a function will remain changes at the global scope.

Nest Arrays

Arrays can be nested inside of arrays.
Example: [1, 2, 3, [4, 5]]
Bracket ([]) notation functions as doubles to access these values.
Example: Array[4][1] = 5

Array Properties and Methods

Array Iterator Methods

Arrays have their own built in methods that enable code to iterate through them like loops. See these methods presented below (more can be found here: MDN Array Iterator Methods)

Objects

Javascript, like other programming languages uses objects extensively. Objects are established by setting a variable equal to values between {}.
Within the {}, we populate key value pairs of data. These are 'key' values, followed by a : and then the 'value.

Example: time : '7:00'.

NOTE: If a key needs to include a space, it needs to be placed between ' '.

Accessing Object Properties

There are two ways to access object properties.

Overwriting or creating new object properties

Object properties can be set or overwritten by setting values equal to a property using bracket or dot notation.
Example: me.sex = 'male'.

The keyword delete can be used to remove a property from an object.
Example: delete me.sex

Adding methods to objects

In addition to properties, objects can have unique functions called methods created within them. Methods can be implemented like this:

or in an even simpler manner leaving out the word function this way:

Once established, methods are called by the object name.methodName().
Example: me.work().

Nesting Objects within objects

Objects can be nested within other objects to represent complex layers of relationships. Once done, aspects of all of the objects can be accessed using a chain of . and [] notation to return interior values. When done, it should look like this:

From here accessing these elements works using a string of dot and bracket notation.
Example: let capFave = spaceship.crew.captain['favorite foods'][0];

Pass by Reference

Functions can easily assign (or re-assign) object properties due to their ability to link to where those objects are stored. Alternatively, functions cannot modify the variable holding the object, as this in the global scope. If an object is set equal to a value in a function, that generally creates an equal variable within the scope of the function, and doesn't impact the global variable.

Advanced Objects Concepts

The this keyword

When running methods inside of an object, the method doesnt automatically have access to the properties on its parent objects (they arent in the same scope.). This is where the keyword this comes into use. It is used like this:

let obj = {
test : 'value',
print() {
return console.log(`This has been a great ${this.value}.`)
}
}

This presents a problem when using an arrow function. Arrow functions automatically bind the this keyword to themselves, and thus a this placed inside will failed to reference the parent object's properties. Avoid using arrow functions when this is needed in code.

Privacy in Objects

Javascript lacks a native way to label data as requiring privacy. In practice, developers in Javascript will usually name properties that shouldn't be changed to begin with an _.
Example: _name = 'Matthew Okoorian'.

Despite this practice, these values can still be replaced in practice. However with the application of getter and setter functions, these _ can be respected as intended.

Getters and Setters

Factory Functions

Factory functions are functions that take a few parameter values and return an object with those parameters set as object properties. Here is an example of what a factory function should look like:

With these factory functions defined, they can be used by call inside of a variable setting as so:

Destructing Shorthand for a Factory Function

The Factory function can be further shorthanded using the following syntax:

const factoryFunction = ('a', 'b', 'c') => {
return { val1: 'a', val2: 'b', val3: 'c' }
}

or this will return an equivalent result:

const factoryFunction = ('a', 'b', 'c') => {
return { 'a', 'b', 'c' }
}

Destructured Variable Assignment

Say you want to assign a variable to an object property. This would typically be done like this.

const myName = me.name

With destructured assignments, the property can be assigned to a variable of a matching name using this syntax:

let {name] = me
or
let {name} = me.names
if the property is on an object within an object.

Built in Object Methods

Conditionals

Conditionals are used for making decisions in coding. They consider a condition, and perform an action based on defined criteria.

The basic structure of an if Javascript statement goes as follows:
if (condition) {

console.log(aResult)
};

Alternatively, following the closing }, an else statement can be added which will run if the condition is false.
Example: ...preceding action} else {
console.log('The first condition failed')
}

Comparison Operators

Conditions commonly compare two values to determine a true or false outcome. The following operators enable those comparisons.

Logical Operators

Logical Operators within conditionals allow one to split or join conditions using And, Or joins or to use Not.

Table 1
Logic AND OR NOT
Syntax && || !

Example: ('test' === 'test' && 'butter !== 'jelly) resolves to true

Truthy and Falsy Values

When a non-Boolean value is passed into a condition, JavaScript has rules for how to evaluate it. It's easier to note the Falsy values.

Example - can use this principle to default a variable to a value.

Example - can use this in a variable declaration with an OR(||) syntax to declare a backup value if one is Falsy.

An example of assigning a variable with a conditional

Ternary Operators

A conditional can be shorthanded using the following notation:
(condition) ? console.log(action1) : console.log(action2)

Using this shorthand, if the condition evaluates to true, the first action triggers. If false, the second will trigger.

Else if Statements

A series of If statements can be combined in a single conditional using Else if...

Example: If (condition) {
console.log(outcome1)
} else if (condition2) {
console.log(outcome2)
} else {
console.log(outcome3)
}

Switch keyword

Finally for conditionals, the Switch keyword can be used to return different actions when a variable is equal to different values.

Loops

Loops are used in code to perform the same code multiple times until a condition has been satisfied. A good example of this requirement would be doing the same action to every item inside of an array. This could result in usually needing a seperate line of code for every item of the array. This is better done using the for keyword.

Example: for (let counter = 0; counter < 4; counter ++) {
console.log(counter);
}

Within the (), the first item initializes a state, the second provides the condition to continue, the third indicates a change to make each time the enclosed code runs.
This code can be very easily reversed to count down as well:

for (let counter = 3; counter >= 0; counter--){
console.log(counter);
}

Coders should be cautious when implementing loops to avoid infinite loops (where the termination condition is never reached). To quit out of this, it may be necessary to hit Ctrl-C to quit in a terminal.

Looping through an array

Looping through arrays is as simple as applying the code above while setting condition variables to compare the iterator to the .length of the array.

Nested Loops

Nested loops can be helpful for comparing values within two arrays. In this way, the loop works through one array, and for each item in it, runs a comparison to all of the items in the other array. See the example below:

While and Do while loops

Where the loop variable exist within the body of the code, a while loop can be used instead. These are set with the keyword while paired with a condition that modified within the body of the code. It will continue to run while the condition evaluates to true.
Example:

A while loop may never run if its condition never occurs in the first place. This can be overcome if needed with a Do while loop. This uses the keyword do, followed by the action in {}, followed by the keyword while and then the condition in ().

The Break and Continue keywords

Inserting the keyword break into a loop will immediately cause it to end. This can be useful when combined with a conditional within a for loop to check a condition, and end the loop when the condition has been satisfied.

The continue keyword will alternatively prevent code downstream from it from running, and will begin the loop again from the top. This can be used to skip a value if a condition is satisified during the running of the loop.

Final Shortcut - The for ..of loop (shown in the Continue example above)

A final approach to for loops occurs to shorthand a for loop that has been applied to all objects within an array. Here values within an array can be set equal to a variable and each fed into a for loop using an of keyword.
Example:
for (const var of array) {
console.log(`I love this ${var}.`);
}

Looping through objects

Objects in arrays can be looped through using the For and In keywords. They work like this:

It should be noted that this always primarily returns the keys. They can be entered in dot or bracket notation to access their values.

Functions

Functions serve to establish re-usable blocks of code that can be deployed repeatedly in our code. They are first class objects in Javascript, and can have properties and methods.

Declaring a function

A function can be declared using the function declaration. This looks like:
function greetWorld() {
console.log('Hello World');
}

Here function serves as a keyword. greetWorld() acts as the identifier for the function (the function itself is actually just the name with no ()), and it is how it gets called later on. Inside of the {} is the function body, or what gets executed when the function is called.

Note: Javascript will allow a function to be called in code before it is declared (called Hoisting). This is not considered to be a good coding practice however.

After a function is declared, it can be called by inserting the name of the function into the code followed by (). Example: greetWorld();

Using Parameters and Arguments

A function can be declared using parameters to enable it to receive variables when it gets called. This looks like the following:

This process enables the use of unique values, or even variables established previously in the code.

Assigning a deault parameter

A default parameter can be set on a function to use in the event that no value is passed in. This looks like this:

Determine what to return with a function

When a function runs, it follows its instructions and returns a result. In the examples above, the function prints text to the console. However, it is also returning a value. If undefined, the function returns the value "Undefined".
Example: first declare function typeA() { console.log('A'); }. if console.log(typeA()) is run, it will retun Undefined, as it prints when run, but when inserted in a print statement, it returns nothing.

Thus, telling a function what to return is as simple as this:

Additional Function Concepts

Coding Concepts

Abstraction

When we code, it is often necessary to simplify tasks for reuse. In this way, a complex multi-stage process can be broken down to subtasks. Subtasks can sometimes be constructed as functions that serve as parameters for other functions. Functions can return functions, and ultimately this nesting can become quite complex while also clarifying the purpose of specific code in a program.

The simplest form of this is to set functions equal to other functions. This may enable use of a function with a clearer name in the context in which it is being used. Because functions have names, running console.log(function.name) can help identify the original function within the script.

High-Order Functions

High-order functions are those that take or return other functions. In this way these functions can provide flexibility around up and downstream use of functions. See the image below for an example.

Iterators