# Introduction to JS (JavaScript)

#### Browser Dev Tools - Console

Open the Browser Dev Tools Console panel using the shortcut `Command + Option + j` for MacOS or `Control + Shift + j` for Linux or Windows.

![Chrome Console Panel](https://i.imgur.com/X70fH4f.png)

#### Running JavaScript in a Web Page

Add a JavaScript file to any html file using a `script` tag.

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Hello World</title>
</head>
<body>
  <h1>Hello World</h1>
  <script src="script.js"></script>
</body>
</html>
```

#### Built-in Functions for "Printing" Things

**`alert`**

```javascript
alert('Hello World')
```

**`console.log`**

```javascript
console.log('Hello World')
```

#### Comments

Commented out lines of code will not be executed. In addition to temporarily preventing some lines of code from running, comments are also used to annotate your code.

```javascript
// This is a single line comment
```

```javascript
/*
This is
a multi-line
comment
*/ 
```

```javascript
// This is
// also
// a "multi-line"
// comment
```

In VSCode, you can quickly toggle comments by using the shortcut `Command + /` for MacOS or `Control + /` for Linux or Windows.

#### Data Types - Primitives

* `string`

  Any number of characters enclosed in backticks or single/double quotes.
* `number`

  Any numerical value (whole number or decimal), `Infinity`, or `NaN`
* `boolean`

  The values `true` and `false`
* `undefined`

  The value of an uninitialised variable.
* `null`

  Represents a missing object value (Objects are a complex data type that will be discussed later).

To check the type of a value, use the `typeof` operator.

```javascript
console.log(typeof "what am i?") // -> "string"
console.log(typeof 42)           // -> "number"
console.log(typeof 42.1)         // -> "number"
console.log(typeof true)         // -> "boolean"
console.log(typeof undefined)    // -> "undefined"
// Gotcha
console.log(typeof null)         // -> "object"
// Not A Number is a number
console.log(typeof NaN)          // -> "number"
```

#### Variables

Variables are a way to store values for reuse later in your code or for labeling data with descriptive names.

JavaScript has three ways to create variables: `const`, `let`, and `var`. The latter is a much older syntax and is rarely, if ever, used in modern JavaScript.

**Variable Naming Rules**

* A variable can be made up of letters, numbers, underscores (`_`), and dollar signs (`$`).
* It cannot start with a number.
* Case sensitive
* Use camelCase for multi-word variable names (not a rule per se but a strong convention)

```javascript
const firstName = 'Tonto'
const breed = 'German Shepherd'
const age = 5
```

**`const` vs `let`**

Once initialised with a value `const` variables cannot be reassigned while `let` can.

```javascript
const lunch = 'Cold pizza' 
lunch = 'burger' // -> TypeError
```

```javascript
let lunch = 'Cold pizza' 
lunch = 'burger'
console.log(lunch) // -> "burger"
```

Because `const`'s can't be reassigned later on, you have to always initialise it with a value. `let` variables can be declared first, then initialised with a value later.

```javascript
const dinner // -> SyntaxError
```

```javascript
let dinner
console.log(dinner) // -> undefined
dinner = 'Soup'
console.log(dinner) // -> "Soup"
```

The convention in JavaScript is to use `const` *unless* you know you need to reassign the variable at some other point in your code, in which case you use `let`.

#### Number & String Operations

**Mathematical Operators**

| Operator | Name           |
| -------- | -------------- |
| `+`      | Addition       |
| `-`      | Subtraction    |
| `*`      | Multiplication |
| `/`      | Division       |
| `%`      | Modulo         |
| `**`     | Exponent       |

*Note* Operator precendence is the same as in your Math class in school (*PEMDAS*).

**String Concatenation & Interpolation**

The `+` operator when used with strings concatenates (or "glues") strings together.

```javascript
const praise = 'Good boy'
const dogName = 'Tonto'
console.log(praise + ' ' + dogName)
```

Alternatively, you can use backtick strings (Template literals) to interpolate the variables in the string.

```javascript
const praise = 'Good boy'
const dogName = 'Tonto'
console.log(`${praise} ${dogName}`)
```

Template literal interpolation isn't limited to variables, it can be any expression that produces a value.

```javascript
const firstNum = 36
const secondNum = 6
console.log(`The sum of ${firstNum} and ${secondNum} is ${firstNum + secondNum}`)
```

### Control Flow - Conditional Statements

Control flow is simply applying conditional logic to how your code is run. You may want to run certain blocks of code but not others, or you might want to run certain code blocks over and over again. We probably wouldn't want to show a user account page to a user who isn't logged in, since there would be no data to display!

#### Types of Control Flow

We're going to learn about two new forms of control flow you already know one!

The first form of control flow is: **linear**.

![linear control flow](https://eloquentjavascript.net/img/controlflow-straight.svg)

> Source: [Eloquent JavaScript, Ch. 02 Program Structure](https://eloquentjavascript.net/02_program_structure.html)

Linear control flow simply means that our data flows through our code, one line after the next. Execution starts at the first line of code, moves on to the second, then the third, and so on until the end of the file, when execution stops.

The second form of control flow is: **conditional**.

![Conditional control
flow](https://eloquentjavascript.net/img/controlflow-if.svg)

> Source: [Eloquent JavaScript, Ch. 02 Program Structure](https://eloquentjavascript.net/02_program_structure.html)

We will often run in to scenarios where we want one block of code to run if, and only if, a particular condition is met. Perhaps we're asking a user for their age and we want to ensure that the value they give us is a number greater than 0. Conditional execution in JavaScript is achieved with the `if` statement:

```javascript
if (age >= 16) {
  console.log('You can drive!')
}
```

In the above snippet of code, we will only see the message `'you can drive!'` ***if*** the `age` variable is `16` or greater. Later, we'll explore `else` and `else if` - ways for us to test other conditions or run code specifically when our condition *is not* met. *We'll dive into this pattern more in a few minutes!*

The third form of control flow is: **looping**. We'll get into that next time.

#### Comparison Operators

| Operator | Name                  |
| -------- | --------------------- |
| `>`      | Greater than          |
| `<`      | Less than             |
| `>=`     | Greater than or equal |
| `<=`     | Less than or equal    |
| `==`     | Equality              |
| `!=`     | Inequality            |
| `===`    | Strict Equality       |
| `!==`    | Strict Inequality     |

**Strict vs Non-strict Equality Comparisons**

It is best practice to use strict equality unless you have a very good reason to not use it. It is more likely that you will get some unexpected results with using non-strict equality comparisons. Compare the [equality tables](https://dorey.github.io/JavaScript-Equality-Table/) of both and you'll see that strict comparisons are more straightforward and predictable.

#### Logical Operators

| Operator | Name |
| -------- | ---- |
| `&&`     | AND  |
| `\|\|`   | OR   |

#### Conditionals

Conditionals are a common feature of programming languages because it's handy to execute different blocks of code depending on whether a condition is met.

Conditionals follow this pattern:

```javascript
if (condition) {
  // code writen here will run if
  // the condition evaluates to true
}
```

The above is a simple conditional statement, with only a single condition. We can add a negative condition (code that will run if the condition is `false`) and we can add additional positive conditions.

If we have code we want to run if our condition is false, we use `else`:

```javascript
if (condition) {
  // code here will run if the condition evaluates to true
} else {
  // code here will run if the condition evaluates to false
}
```

If we want to test multiple conditions, we can do so by combining `else` and `if`:

```javascript
if (condition) {
  // code here will run if the condition evaluates to true
} else if (anotherCondition) {
  // code here will run if the second condition evaluates to true
} else {
  // code here will run if none of the conditions evaluate to true
}
```

We can add as many `else`/`if` statements as we want, one for each condition we want to check, but after a while our code becomes hard to read:

```javascript
const assignmentCompletion = 0

if (assignmentCompletion === 0) {
  console.log("Work on your homework!")
} else if (assignmentCompletion === 1) {
  console.log("Good work, still more to go")
} else if (assignmentCompletion === 2) {
  console.log("Almost there!")
} else {
  console.log("You are done!")
}
```

If you want to test two conditions without using and `else`/`if` you can do so by using the logical operators (`&&` and `||`):

```javascript
if (condition && condition) {
  // this code will run if both conditions are true
}

if (condition || condition) {
  // this code will run if one of the conditions is true
}
```

```javascript
const customerAge = 20
if (customerAge >= 18 && customerAge <= 22) {
  console.log('student discount')
}
```

```javascript
const num = 42
if (num % 2 === 0 || num % 3 === 0) {
  console.log(`divisible by either 2 or 3`)
}
```

We can also add nested if/else statements:

```javascript
const assignmentCompletion = 0
const checkpointScore = 100

if(assignmentCompletion === 0) {
  console.log("Work on your homework!")
  if(checkpointScore === 100) {
    console.log("Well you did great on the quiz at least")
  } else if(checkpointScore < 60) {
    console.log("Time for a retake!")
  }
} else if( assignmentCompletion > 80 ) {
  console.log("You're doing great!")
} else {
  console.log("Keep on truckin")
}
```

There's no (practical) limit to the depth of if / else statements. But you can imagine that this gets difficult to read and understand fairly quickly. Simpler is better!

#### Changing Content in a Webpage

We'll dive deeper into this topic in the next few weeks. For now, here's a quick code snippet that shows you how to manipulate the content in a webpage "live".

```html
<h1 id="heading">Lorem Ipsum Dolor Sit Amet</h1>
```

```javascript
const name = prompt('Nu fone hu dis?')
const heading = document.querySelector('#heading')
heading.textContent = 'Hello ' + name
```
