From 37d82f4cbc99bb3f7681269e678c24401a3d0deb Mon Sep 17 00:00:00 2001 From: Bryan C Guner <66654881+bgoonz@users.noreply.github.com> Date: Sat, 3 Apr 2021 19:15:08 -0400 Subject: [PATCH 1/4] Set theme jekyll-theme-slate --- _config.yml | 1 + index.md | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 _config.yml create mode 100644 index.md diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..c741881 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-slate \ No newline at end of file diff --git a/index.md b/index.md new file mode 100644 index 0000000..4148f26 --- /dev/null +++ b/index.md @@ -0,0 +1,37 @@ +## Welcome to GitHub Pages + +You can use the [editor on GitHub](https://github.com/bgoonz/lambda-prep/edit/gh-pages/index.md) to maintain and preview the content for your website in Markdown files. + +Whenever you commit to this repository, GitHub Pages will run [Jekyll](https://jekyllrb.com/) to rebuild the pages in your site, from the content in your Markdown files. + +### Markdown + +Markdown is a lightweight and easy-to-use syntax for styling your writing. It includes conventions for + +```markdown +Syntax highlighted code block + +# Header 1 +## Header 2 +### Header 3 + +- Bulleted +- List + +1. Numbered +2. List + +**Bold** and _Italic_ and `Code` text + +[Link](url) and ![Image](src) +``` + +For more details see [GitHub Flavored Markdown](https://guides.github.com/features/mastering-markdown/). + +### Jekyll Themes + +Your Pages site will use the layout and styles from the Jekyll theme you have selected in your [repository settings](https://github.com/bgoonz/lambda-prep/settings). The name of this theme is saved in the Jekyll `_config.yml` configuration file. + +### Support or Contact + +Having trouble with Pages? Check out our [documentation](https://docs.github.com/categories/github-pages-basics/) or [contact support](https://support.github.com/contact) and we’ll help you sort it out. From faf7ba7acc465ff2328213cb8240a5eabc312ccc Mon Sep 17 00:00:00 2001 From: Bryan C Guner <66654881+bgoonz@users.noreply.github.com> Date: Sat, 3 Apr 2021 19:15:13 -0400 Subject: [PATCH 2/4] Create index.md From 90fa92deef3a4660c84432b53cdef42dc26671a6 Mon Sep 17 00:00:00 2001 From: Bryan C Guner <66654881+bgoonz@users.noreply.github.com> Date: Sat, 3 Apr 2021 19:15:45 -0400 Subject: [PATCH 3/4] Update index.md --- index.md | 3460 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 3439 insertions(+), 21 deletions(-) diff --git a/index.md b/index.md index 4148f26..756e3e8 100644 --- a/index.md +++ b/index.md @@ -1,37 +1,3455 @@ -## Welcome to GitHub Pages +# Prep-Work -You can use the [editor on GitHub](https://github.com/bgoonz/lambda-prep/edit/gh-pages/index.md) to maintain and preview the content for your website in Markdown files. +## [deployment](https://60637489113cfe1345c7fcf9--jolly-shannon-bbcd09.netlify.app/) -Whenever you commit to this repository, GitHub Pages will run [Jekyll](https://jekyllrb.com/) to rebuild the pages in your site, from the content in your Markdown files. -### Markdown +0.\) Links: -Markdown is a lightweight and easy-to-use syntax for styling your writing. It includes conventions for +| Name | Hyperlink | +| :-------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| OKTA | [https://lambdaschoolsso.okta.com/login/login.htm?fromURI=%2Fapp%2FUserHome](https://lambdaschoolsso.okta.com/login/login.htm?fromURI=%2Fapp%2FUserHome) | +| Calendar | [https://calendar.google.com/calendar/u/0/embed?src=c\_2q0kvam9h9k5i6t40qp5n18dh8@group.calendar.google.com](https://calendar.google.com/calendar/u/0/embed?src=c_2q0kvam9h9k5i6t40qp5n18dh8@group.calendar.google.com) | +| Slack | [https://app.slack.com/client/T4JUEB3ME/G01QG65CN75](https://app.slack.com/client/T4JUEB3ME/G01QG65CN75) | +| | | +| | | +| | | +| | | +| | | +| Prep Work | [https://apply.lambdaschool.com/courses/web/](https://apply.lambdaschool.com/courses/web/) | -```markdown -Syntax highlighted code block -# Header 1 -## Header 2 -### Header 3 -- Bulleted -- List -1. Numbered -2. List -**Bold** and _Italic_ and `Code` text +1.\) Platforms we need while attending class: -[Link](url) and ![Image](src) + + +2.\) Web Development Software: + + + +3.\) Pre-Course Work + + +``` +. +├── README.html +├── README.md +├── SUMMARY.html +├── SUMMARY.md +├── codeswing.json +├── comparison.png +├── demo.html +├── directory.html +├── index.html +├── javascript-practice +│ ├── 00_expressions_variables +│ │ ├── exercises +│ │ │ ├── A_executing_code_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── B_expressions_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── C_variables_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── D_string_indexing_and_methods_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ +│ │ ├── +│ │ └── solutions +│ │ ├── A_executing_code_solution +│ │ │ ├── age.js +│ │ │ ├── greeting.js +│ │ │ ├── +│ │ │ ├── thirsty.js +│ │ │ └── whoami.js +│ │ ├── B_expressions_solution +│ │ │ ├── boolean-expressions.js +│ │ │ ├── comparisons.js +│ │ │ ├── number-expressions.js +│ │ │ ├── +│ │ │ └── string-expressions.js +│ │ ├── C_variables_solution +│ │ │ ├── four.js +│ │ │ ├── one.js +│ │ │ ├── +│ │ │ ├── three.js +│ │ │ ├── two.js +│ │ │ └── zero.js +│ │ ├── D_string_indexing_and_methods_solution +│ │ │ ├── a-tedious-task.js +│ │ │ ├── dare-to-decipher.js +│ │ │ ├── proper-patterns.js +│ │ │ ├── +│ │ │ └── small-string-snippets.js +│ │ +│ ├── 01_conditionals +│ │ ├── exercises +│ │ │ ├── A_conditionals_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ +│ │ ├── +│ │ └── solutions +│ │ ├── A_conditionals_solution +│ │ │ ├── one.js +│ │ │ ├── +│ │ │ ├── three.js +│ │ │ ├── two.js +│ │ │ └── zero.js +│ │ +│ ├── 02_functions +│ │ ├── exercises +│ │ │ ├── A_functions_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── B_functions_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── C_functions_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ +│ │ ├── +│ │ └── solutions +│ │ ├── A_functions_solution +│ │ │ ├── average.js +│ │ │ ├── ends-with-t.js +│ │ │ ├── half.js +│ │ │ ├── is-div-by-4.js +│ │ │ ├── is-long.js +│ │ │ ├── keep-it-quiet.js +│ │ │ ├── +│ │ │ ├── snippet-0-1.js +│ │ │ ├── snippet-0-2.js +│ │ │ ├── snippet-0-3.js +│ │ │ └── snippet-0-4.js +│ │ ├── B_functions_solution +│ │ │ ├── ends-in-ly.js +│ │ │ ├── funny-sound.js +│ │ │ ├── longer.js +│ │ │ ├── one-or-none.js +│ │ │ ├── parity.js +│ │ │ ├── +│ │ │ ├── starts-with-r.js +│ │ │ ├── string-size.js +│ │ │ └── wacky-word.js +│ │ ├── C_functions_solution +│ │ │ ├── average-of-four.js +│ │ │ ├── case-changer.js +│ │ │ ├── contains.js +│ │ │ ├── divisible.js +│ │ │ ├── in-range.js +│ │ │ ├── larger.js +│ │ │ ├── number-change.js +│ │ │ +│ │ +│ ├── 03_loops +│ │ ├── exercises +│ │ │ ├── A_loops_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── B_loops_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── C_loops_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ +│ │ ├── +│ │ └── solutions +│ │ ├── A_loops_solution +│ │ │ ├── count-up.js +│ │ │ ├── evens.js +│ │ │ ├── min-to-max.js +│ │ │ ├── one-to-four.js +│ │ │ ├── +│ │ │ ├── snippet-1.js +│ │ │ ├── snippet-2.js +│ │ │ ├── snippet-3.js +│ │ │ ├── snippet-4.js +│ │ │ ├── snippet-5.js +│ │ │ └── string-iterate.js +│ │ ├── B_loops_solution +│ │ │ ├── div-by-either.js +│ │ │ ├── five-multiples-of.js +│ │ │ ├── no-ohs.js +│ │ │ ├── odd-sum.js +│ │ │ ├── product-up-to.js +│ │ │ ├── +│ │ │ ├── string-repeater.js +│ │ │ └── sum-up-to.js +│ │ ├── C_loops_solution +│ │ │ ├── censor-e.js +│ │ │ ├── divisible-range.js +│ │ │ ├── fizz-buzz.js +│ │ │ ├── raise-power.js +│ │ │ ├── remove-capitals.js +│ │ │ ├── reverse-iterate.js +│ │ │ +│ │ +│ ├── 04_arrays +│ │ ├── exercises +│ │ │ ├── A_arrays_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── B_arrays_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── C_arrays_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ +│ │ ├── +│ │ └── solutions +│ │ ├── A_arrays_solution +│ │ │ ├── bleep-vowels.js +│ │ │ ├── divisors.js +│ │ │ ├── filter-long-words.js +│ │ │ ├── num-odds.js +│ │ │ ├── +│ │ │ ├── stay-positive.js +│ │ │ ├── strings-to-lengths.js +│ │ │ └── total.js +│ │ ├── B_arrays_solution +│ │ │ ├── choose-divisibles.js +│ │ │ ├── make-acronym.js +│ │ │ ├── maximum.js +│ │ │ ├── reverse-array.js +│ │ │ ├── +│ │ │ ├── word-count.js +│ │ │ └── your-average-function.js +│ │ ├── C_arrays_solution +│ │ │ ├── alternating-caps.js +│ │ │ ├── common-elements.js +│ │ │ ├── lengthiest-word.js +│ │ │ ├── number-range.js +│ │ │ ├── remove-short-words.js +│ │ │ +│ │ +│ ├── 05_nesting +│ │ ├── exercises +│ │ │ ├── A_nested_loops_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── B_two_dimensional_arrays_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── C_more_problems_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ +│ │ ├── +│ │ └── solutions +│ │ ├── A_nested_loops_solution +│ │ │ ├── pair-print.js +│ │ │ ├── print-combinations.js +│ │ │ ├── +│ │ │ ├── snippet-1.js +│ │ │ ├── snippet-2.js +│ │ │ ├── snippet-3.js +│ │ │ ├── snippet-4.js +│ │ │ ├── snippet-5.js +│ │ │ └── two-sum.js +│ │ ├── B_two_dimensional_arrays_solution +│ │ │ ├── make-matrix.js +│ │ │ ├── print-2d.js +│ │ │ ├── +│ │ │ ├── total-product.js +│ │ │ ├── two-sum-pairs.js +│ │ │ └── zipper.js +│ │ ├── C_more_problems_solution +│ │ │ ├── remove-dupes.js +│ │ │ ├── remove-first-vowel.js +│ │ │ ├── remove-vowels.js +│ │ │ ├── +│ │ │ ├── shorten-long-words.js +│ │ │ └── spam.js +│ │ +│ ├── 06_decomposition_pattern +│ │ ├── A_decomposing_problems_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ ├── B_decomposing_problems_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ ├── C_decomposing_problems_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ +│ ├── 07_objects +│ │ ├── A_objects_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ ├── B_objects_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ ├── C_objects_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ +│ ├── 08_higher_order_functions +│ │ ├── A_native_callback_methods_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ ├── B_native_callback_methods_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ +│ +├── js.js +├── one-of-every-tag.html +├── readme +│ ├── README.html +│ ├── README_files +│ │ ├── katex.min.css +│ │ +│ +├── resources.html +├── resources.md +├── script.js +├── style.css +└── tree.md + +66 directories, 241 files + + + + + +``` +# WEEK 1
*Introduction to JavaScript (Part 1)* {ignore=true} +________________________________________________________________________________ + + + +[**Expression Learning Objectives**](#expression-learning-objectives) +[**Intro to Functions Learning Objectives**](#intro-to-functions-learning-objectives) +- [Hello World](#hello-world) + - [Getting visual feedback in your programs](#getting-visual-feedback-in-your-programs) + - [Code comments](#code-comments) +- [The Number Type](#the-number-type) + - [All the numbers](#all-the-numbers) + - [The basic arithmetic operators](#the-basic-arithmetic-operators) +- [The String Type](#the-string-type) + - [Writing a valid string](#writing-a-valid-string) + - [Calculating length](#calculating-length) + - [Indexing a string](#indexing-a-string) + - [Concatenation](#concatenation) +- [The Boolean Type](#the-boolean-type) + - [Logical Operators](#logical-operators) + - [De Morgan's Law](#de-morgans-law) +- [Comparison Operators](#comparison-operators) + - [The relative comparators](#the-relative-comparators) + - [=== vs ==](#vs) +- [Basic Variables](#basic-variables) + - [Initializing a variable](#initializing-a-variable) + - [Manipulating variables](#manipulating-variables) + - [NaN](#nan) +- [Introduction to Functions](#introduction-to-functions) + - [Writing Functions](#writing-functions) + - [Invoking or "calling" a function](#invoking-or-calling-a-function) + - [Returning a value](#returning-a-value) + - [The importance of naming](#the-importance-of-naming) +- [Parameters and Arguments](#parameters-and-arguments) + - [The difference between Parameters and Arguments](#the-difference-between-parameters-and-arguments) + +[**Control Flow and Array Learning Objectives**](#control-flow-and-array-learning-objectives) +- [Control Flow - Conditional Statements](#control-flow-conditional-statements) + - [A Quick Word on Syntax](#a-quick-word-on-syntax) + - [Writing Conditional Statements](#writing-conditional-statements) +- [Mutually Exclusive Conditions](#mutually-exclusive-conditions) + - [When to use if statements](#when-to-use-if-statements) +- [Control Flow - Looping](#control-flow-looping) + - [Looping](#looping) + - [Translating From One Loop to Another](#translating-from-one-loop-to-another) +- [The Array Type](#the-array-type) + - [Using arrays](#using-arrays) + - [Indexing arrays](#indexing-arrays) + - [Working with arrays](#working-with-arrays) + - [Concatenation with arrays](#concatenation-with-arrays) + +[**Intermediate Functions Learning Objectives**](#intermediate-functions-learning-objectives) +- [Function Expressions](#function-expressions) + - [Functions as first-class objects](#functions-as-first-class-objects) +- [Two-Dimensional Arrays (2D Arrays)](#two-dimensional-arrays-2d-arrays) + - [Multidimensional Arrays](#multidimensional-arrays) + - [Iterating through 2D Arrays](#iterating-through-2d-arrays) + - [When is a 2D array practical?](#when-is-a-2d-array-practical) +- [Mutability in JavaScript](#mutability-in-javascript) + - [What is mutability?](#what-is-mutability) + - [Mutable or immutable, that is the question](#mutable-or-immutable-that-is-the-question) + - [The mutability misconception](#the-mutability-misconception) +- [Array Splice](#array-splice) + - [Notation](#notation) + - [What can Array#splice do?](#what-can-arraysplice-do) +- [String#split and Array#join](#stringsplit-and-arrayjoin) + - [String#split](#stringsplit) + - [Array#join](#arrayjoin) + - [A clever combination](#a-clever-combination) +- [Determining Types](#determining-types) + - [The typeof operator](#the-typeof-operator) + - [How to tell if a value is an array](#how-to-tell-if-a-value-is-an-array) + - [Practical use in "real" code](#practical-use-in-real-code) +- [The Null Type (And Undefined)](#the-null-type-and-undefined) + - [A type with only one value](#a-type-with-only-one-value) + - [The meaning of null](#the-meaning-of-null) + - [The absence of a value](#the-absence-of-a-value) + - [An unknown value](#an-unknown-value) + - [Checking if a value is null](#checking-if-a-value-is-null) + - [Oh, and there's that undefined value, too](#oh-and-theres-that-undefined-value-too) + - [What happens when...](#what-happens-when) +- [Catch Me If You Can](#catch-me-if-you-can) + - [Structured exception handling](#structured-exception-handling) + - [Try and catch](#try-and-catch) + - [How can I make my own errors?](#how-can-i-make-my-own-errors) + - [What else is there?](#what-else-is-there) + - [How do I best use this?](#how-do-i-best-use-this) + + +________________________________________________________________________________ +# WEEK-01 DAY-1
*Function Introduction* {ignore=true} +________________________________________________________________________________ +# Expression Learning Objectives + +Below is a complete list of the terminal learning objectives for this lesson. +When you complete this lesson, you should be able to perform each of the +following objectives. These objectives capture how you may be evaluated on the +assessment for this lesson. + +1. Given a working REPL interface, write and execute a statement that will print + "hello world" using console.log +2. Identify that strings are a list of characters defined by using double or + single quotes +3. Given an arithmetic expression using +, -, \*, /, %, compute its value +4. Given an expression, predict if its value is NaN +5. Construct the truth tables for &&, ||, ! +6. Given an expression consisting of >, >=, ===, <, <=, compute it's value +7. Apply De Morgan's law to a boolean expression +8. Given an expression that utilizes operator precedence, compute its value +9. Given an expression, use the grouping operator to change it's evaluation +10. Given expressions using == and ===, compute their values +11. Given a code snippet using postfix ++, postfix --, +=, -=, /=, \*=, predict + the value of labeled lines +12. Create and assign a variable using `let` to a string, integer, and a + boolean. Read its value and print to the console.l learning objectives for this lesson. +When you complete this lesson, you should be able to perform each of the +following objectives. These objectives capture how you may be evaluated on the +assessment for this lesson. + +1. Given a working REPL interface, write and execute a statement that will print + "hello world" using console.log +2. Identify that strings are a list of characters defined by using double or + single quotes +3. Given an arithmetic expression using +, -, \*, /, %, compute its value +4. Given an expression, predict if its value is NaN +5. Construct the truth tables for &&, ||, ! +6. Given an expression consisting of >, >=, ===, <, <=, compute it's value +7. Apply De Morgan's law to a boolean expression +8. Given an expression that utilizes operator precedence, compute its value +9. Given an expression, use the grouping operator to change it's evaluation +10. Given expressions using == and ===, compute their values +11. Given a code snippet using postfix ++, postfix --, +=, -=, /=, \*=, predict + the value of labeled lines +12. Create and assign a variable using `let` to a string, integer, and a + boolean. Read its value and print to the console. + +________________________________________________________________________________ +# Intro to Functions Learning Objectives + +Below is a complete list of the terminal learning objectives for this lesson. +When you complete this lesson, you should be able to perform each of the +following objectives. These objectives capture how you may be evaluated on the +assessment for this lesson. + +1. Define a function using function declaration +2. Define a function that calculates the average of two numbers, call it, + pass in arguments, and print it's return value +3. Identify the difference between parameters vs argument terminal learning objectives for this lesson. +When you complete this lesson, you should be able to perform each of the +following objectives. These objectives capture how you may be evaluated on the +assessment for this lesson. + +1. Define a function using function declaration +2. Define a function that calculates the average of two numbers, call it, + pass in arguments, and print it's return value +3. Identify the difference between parameters vs arguments +________________________________________________________________________________ +# Hello World + +Hey Programmer! Welcome to the JavaScript module. In the next few sections, +we'll be learning the fundamentals of the JavaScript programming language. If +it's your first time programming, don't worry; we designed this course +especially for you. We'll have you executing your first lines of code in no +time! + +When you finish this article, you should be able to: + +- use the `console.log` command to print out messages +- use double slashes (`//`) to write code comments + +## Getting visual feedback in your programs + +The first command we'll learn in JavaScript is `console.log`. This command is +used to _print_ something onto the screen. As we write our first lines of code, +we'll be using `console.log` frequently as a way to visually see the output of +our programs. Let's write our first program: + +```javascript +console.log("hello world"); +console.log("how are you?"); +``` + +Executing the program above would print out the following: + +```plaintext +hello world +how are you? +``` + +Nothing too ground breaking here, but pay close attention to the exact way we +wrote the program. In particular, notice how we lay out the periods, +parentheses, and quotation marks. We'll also terminate lines with semicolons +(;). + +> Depending on how you structure your code, sometimes you'll be able to omit +> semicolons at the end of lines. For now, you'll want to include them +> just as we do. + +### Syntax + +We refer to the exact arrangement of the symbols, characters, and keywords as +**syntax**. These details matter - your computer will only be able to +"understand" proper JavaScript syntax. A programming language is similar to a +spoken language. A spoken language like English has grammar rules that we should +follow in order to be understood by fellow speakers. In the same way, a +programming language like JavaScript has syntax rules that we ought to follow! + +As you write your first lines of code in this new language, you may make many +syntax errors. Don't get frustrated! This is normal - all new programmers go +through this phase. Every time we recognize an error in our code, we have an +opportunity to reinforce your understanding of correct syntax. Adopt a growth +mindset and learn from your mistakes. + +Additionally, one of the best things about programming is that we can get such +immediate feedback from our creations. There is no penalty for making a mistake +when programming. Write some code, run the code, read the errors, fix the +errors, rinse and repeat! + +## Code comments + +Occasionally we'll want to leave **comments** or notes in our code. Commented +lines will be ignored by our computer. This means that we can use comments to +write plain english or temporarily avoid execution of some JavaScript lines. The +proper _syntax_ for writing a comment is to begin the line with double forward +slashes (`//`): + +```javascript +// let's write another program!!! +console.log("hello world"); + +// console.log("how are you?"); + +console.log("goodbye moon"); +``` + +The program above would only print: + +```plaintext +hello world +goodbye moon +``` + +Comments are useful when annotating pieces of code to offer an explanation of +how the code works. We'll want to strive to write straightforward code that is +self-explanatory when possible, but we can also use comments to add additional +clarity. The real art of programming is to write code so elegantly that it is +easy to follow. + +"Simplicity is prerequisite for reliability." — Edsger W. Dijkstra + +## What you've learned + +- `console.log` can be used to print to the screen +- using `//` at the front of a line will turn it into a comment; comments are + ignored by JavaScript + +________________________________________________________________________________ +# The Number Type + +The **Number** data type in JavaScript does exactly what you expect! It is used +to represent any numerical values, this includes integers and decimal numbers. +As one of our first data types, we'll be interested in what operations we can +use with numbers. + +When you finish this article, you should be able to: + +- predict the evaluation of arithmetic expressions +- explain the order of operations for JavaScript's arithmetic operators +- use the grouping operator, `()`, to manipulate the order of operations in an + expression + +## All the numbers + +JavaScript's **Number** encompasses numerical values. All of the following values are of number type: + +```javascript +42; +-5; +3.14159; +7.0; +``` + +## The basic arithmetic operators + +For any given data type, we're interested in what operations we can perform with +that type. We use the word _operator_ to refer to the symbol that performs a +particular _operation_. For example, the `+` operator performs the addition +operation. Here are the common arithmetic operators in JS: + +- `+` (addition) +- `-` (subtraction) +- `*` (multiplication) +- `/` (division) +- `%` (modulo) + +With number values and arithmetic operators in hand, we can evaluate our first +expressions: + +```javascript +console.log(2 + 3); // => 5 +console.log(42 - 42); // => 0 +console.log(-4 * 1.5); // => -6 +console.log(25 / 8); // => 3.125 +``` + +Nothing too groundbreaking about the results above. An expression consists of +values and operators. JavaScript will evaluate an expression into a single +value. + +We can write more complex expressions using multiple operators. However, we'll +want to be aware of the general math order of operations. That is, we perform +multiplication-division operations first and then addition-subtraction +operations. To force a specific order of operation, we can use the grouping +operator, `( )`, around a part of the expression: + +```javascript +console.log(5 * 3 + 2); // => 17 +console.log(2 + 3 * 5); // => 17 +console.log((2 + 3) * 5); // => 25 +``` + +### The modulo operation + +All of the math operators listed above are the simple operations you use +everyday, except for maybe modulo `%`. **Modulo gives us the remainder that +results from a division.** For example, `10 % 3` is 1 because when we divide 10 +by 3, we are left with a remainder of 1. We can read `10 % 3` as "ten modulo +three" or "ten mod three." + +```javascript +console.log(10 % 3); // => 1 +console.log(14 % 5); // => 4 +console.log(20 % 17); // => 3 +console.log(18 % 6); // => 0 +console.log(7 % 9); // => 7 +``` + +Modulo is a very useful operation in the realm of computers. We can use it to +check the divisibility of numbers, whether numbers are even, whether they are +prime, and much, much more. Don't take this seemingly simple operation from +granted! We'll provide a ton of practice using these modulo patterns as we move through the course. + +In the order of operations, modulo has the the same precedence as +multiplication-division. So our complete order of math operations in JS is +parentheses, multiplication-division-modulo, addition-subtraction. + +```javascript +// modulo has precedence over addition +console.log(4 + 12 % 5); // => 6 +console.log((4 + 12) % 5); // => 1 +``` + +## What you've learned + +- The **Number** type is used to represent integer and decimal values +- The operators `+`, `-`, `/`, `*` perform the normal math operations of + addition, subtraction, division, multiplication respectively +- `a % b` returns the remainder when we divide `a` by `b`; we call this + operation modulo +- JavaScript follows the usual mathematical order of operations and we can use + the `()` to force precedence + +________________________________________________________________________________ +# The String Type + +This article is about one of JavaScript's primitive data types, **String**. +Strings are what we'll use to represent textual data. This means that strings +are useful in representing things like messages, names, poems, and so on. A +string is a sequence of characters. + +When you finish this article, you should be able to: + +- Write strings using correct syntax +- Use `.length` to obtain a count of the numbers of characters that comprise a + string +- Index a string to refer to a single character +- Concatenate strings together + +## Writing a valid string + +Strings are always wrapped by a pair of single quotation marks (`'`) or by a +pair of double quotation marks (`"`). Between the enclosing quotation marks, we +can put any characters! Here are a six examples of strings: + +```javascript +"potato"; +"New York"; +"azablan@.io"; +"Follow the yellow brick road, please!"; +"365 days a year"; +""; +``` + +Above, notice that we are free to mix in **any** characters into a string. This +includes spaces, numerics, punctuation, and other symbols. The sixth string +above is the empty string; it contains zero characters! + +You are probably wondering why we are allowed to use either single or double +quotes when denoting a string - why is this useful? Maybe we want a string that +_contains_ quotation marks: + +```javascript +// valid strings +'Shakespeare wrote, "To be or not to be"'; +"That's a great string"; +``` + +```javascript +// invalid string +'That's a bad string' +``` + +If we want to use a single quote as a character of a string, we simply need to +enclose the string in double quotes, and vice versa. + +## Calculating length + +Since a single string can contain any number of characters, we may find it +useful to count the number of characters in a string using `.length`: + +```javascript +console.log("ramen".length); // => 5 +console.log("go home!".length); // => 8 +console.log("".length); // => 0 +``` + +## Indexing a string + +Strings consist of multiple characters. These characters are numbered by +**indices** starting at 0. So in the string `'bootcamp'`, `'b'` is at index 0, +`'o'` is at index 1, `'o'` is at index 2, `'t'` is at index 3, and so on. We can +look at particular characters of a string by using `[]` and specifying an index: + +```javascript +console.log("bootcamp"[0]); // => 'b' +console.log("bootcamp"[1]); // => 'o' +console.log("bootcamp"[2]); // => 'o' +console.log("bootcamp"[3]); // => 't' +console.log("bootcamp"[7]); // => 'p' +console.log("bootcamp"[10]); // => undefined +console.log("bootcamp"[-3]); // => undefined +``` + +In general, when we index a string using the expression `string[i]`, we get back +the **single character** at position `i`. Looking at the last two examples +above, if we use an invalid index with a string, the value returned is +`undefined`. This makes since because there is no character at the given +position! It's also worth mentioning that an index should always be a number. + +### The classic "off by one" error + +Bear in mind that indices begin at 0 and not 1! Forgetting this nuance can lead +to incorrect code for both new and experienced programmers alike. Let's hone in +on an important distinction: the index of the last character of a string is +always one less than it's length. + +```javascript +console.log("cat".length); // => 3 +console.log("cat"[3]); // => undefined +console.log("cat"[2]); // => 't' +``` + +In other words, although the `length` of `'cat'` is 3, the index of the last +character (`'t'`) is 2. + +### Using indexOf + +We can also calculate the index of a given character within a string by using +`indexOf`: + +```javascript +console.log("bagel".indexOf("b")); // => 0 +console.log("bagel".indexOf("a")); // => 1 +console.log("bagel".indexOf("l")); // => 4 +console.log("bagel".indexOf("z")); // => -1 +``` + +If we attempt to search for a character that is **not** present in a string, +`indexOf` will return -1. This makes sense because we know that -1 is not a +valid string index. The smallest index possible is 0! + +If we search for a character that appears more than once in a string, +`indexOf` will return the index of the first occurance of that character. + +We can also use `indexOf` to search for a substring of characters. Under this +circumstance, `indexOf` will return the index where the substring begins in the +main string: + +```javascript +console.log("door hinge".indexOf("oor")); // => 1 +console.log("door hinge".indexOf("hi")); // => 5 +console.log("door hinge".indexOf("hint")); // => -1 +``` + +## Concatenation + +Concatenation is just a fancy word for joining strings together into a single +string. To concatenate strings, we use the `+` operator: + +```javascript +console.log("hello" + "world"); // => 'helloworld' +console.log("goodbye" + " " + "moon"); // => 'goodbye moon' +``` + +## What you've learned + +- a **String** is a data type that contains multiple characters enclosed in + quotation marks +- `string.length` returns the number of characters in the `string` +- each character of a string is associated with a number index; the first + character of a string is at index 0 +- we can use `string.indexOf(char)` to obtain the index of `char` within + `string`; if `char` is not found, then -1 is returned +- we can use `+` to concatenate multiple strings, combining them into a single + string + +________________________________________________________________________________ +# The Boolean Type + +The **Boolean** data type is perhaps the simplest type since there are only two +possible values, `true` and `false`. However, we'll find booleans very useful +because they will act as components of later concepts. As programmers, we'll use +booleans to describe the validity of statements. In an abstract sense, _"Today +is Monday"_ and _"one plus one equals ten"_ are examples of statements with +boolean values. That is, they are either `true` or `false`. + +When you finish this article, you should be able to: + +- predict the evaluation of expressions that use the boolean operations of `!`, + `||`, and `&&` +- explain DeMorgan's law + +## Logical Operators + +In the long run, we'll be using booleans to establish logic in our code. For +this reason, the _boolean operators_ can also be referred to as the _logical +operators_. There are only three such operators: + +- `!` (not) +- `&&` (and) +- `||` (or) + +### Logical NOT + +The not (`!`) operator will reverse a boolean value: + +```javascript +console.log(!true); // => false +console.log(!false); // => true +console.log(!!false); // => false +``` + +It's worth mentioning that `!` is a unary operator. This means that the not +operation is applied to a single value. This is in contrast to a binary operator +such as multiplication, which is applied between two values. It does not make +sense to `!` two values together. + +### Logical AND + +The and (`&&`) operator will take two boolean values and will only evaluate to +`true` when both input values are `true`. Otherwise, it will return `false`: + +```javascript +console.log(false && false); // => false +console.log(false && true); // => false +console.log(true && false); // => false +console.log(true && true); // => true +``` + +### Logical OR + +The or (`||`) operator will take two boolean values and will only evaluate to +`false` when both input values are `false`. Otherwise, it will return `true`: + +```javascript +console.log(false || false); // => false +console.log(false || true); // => true +console.log(true || false); // => true +console.log(true || true); // => true +``` + +### Logical order of operations + +We can write boolean expressions that consist of multiple logical operations, but we should be aware of the order of operations. JavaScript will evaluate `!` then `&&` then `||`. + +```javascript +console.log(true || true && false); // => true +console.log(false && !(false || true)); // => false +``` + +In general, `A || B && C` is equivalent to `A || (B && C)` where `A`, `B`, `C` are booleans. + +## De Morgan's Law + +A common mistake in boolean logic is to incorrectly distribute `!` across parentheses. Say we had boolean values of `A`, `B`. Here is something to remember: + +* `!(A || B)` is equivalent to `!A && !B` +* `!(A && B)` is equivalent to `!A || !B` + + +In other words, to correctly distribute `!` across parentheses, we must also flip the operation within parentheses. Beware that: + +* `!(A || B)` is not equivalent to `!A || !B` +* `!(A && B)` is not equivalent to `!A && !B` + +We call this property **De Morgan's Law**. Shout out to Augustus De Morgan of Great Britain. + +## What you've learned + +* `!`, `&&`, `||` are the boolean operators that we can use to establish logic in our code +* De Morgan's Law should be used to distribute `!` against parentheses + +These are just the basics of the type. We'll be seeing more booleans in the upcoming section, so stay tuned for that! + +________________________________________________________________________________ +# Comparison Operators + +In our previous introduction to the boolean data type, we described booleans as +way to represent the validity of an expression. We'll continue this conversation +by exploring **comparison** operators. As you learn about these operators, bear +in mind that all comparisons will result in a boolean, `true` or `false`. + +When you finish this article, you should be able to: + +- Predict the result of expressions that utilize the operators `>`, `<`, `>=` + `<=`, `===`, and `!==` +- Explain the difference between the equality operators `==` and `===` + +## The relative comparators + +- `>` (greater than) +- `<` (less than) +- `>=` (greater than or equal to) +- `<=` (less than or equal to) +- `===` (equal to) +- `!==` (not equal to) + +Using these operators is pretty straightforward. Here are a few examples: + +```javascript +console.log(10 > 5); // => true +console.log(10 < 5); // => false +console.log(1 < 7); // => true +console.log(7 <= 7); // => true +console.log(5 === 6); // => false +console.log(5 !== 6); // => true +console.log("a" !== "A"); // => true +console.log(false === false); // => true +``` + +Notice that a comparison expression always evaluate to a boolean value (`true` +or `false`). Comparison operators like `===` are a useful to compare strings, +booleans, etc. not just numbers. + +**Did you know?** `'a' < 'b'` is valid JS code? When you relatively compare +strings using `>` or `<` you will be comparing them lexicographically. +Lexicographically is fancy shmancy talk for "dictionary" order! A "lesser" +string is one that would appear earlier in the dictionary: + +```javascript +console.log("a" < "b"); // => true +console.log("apple" < "abacus"); // => false +console.log("app" < "apple"); // => true +console.log("zoo" > "mississippi"); // => true +``` + +**Gotcha** capitilized letters are considered lexicographically less than +lower case letters. i.e "A" < "z" // => true. + + +## === vs == + +In JavaScript there are two equality operators triple-equals (`===`) and +double-equals (`==`). The operators differ in how they compare across differing +types. Triple-equals performs the _strict equality_, meaning it will only return +`true` if the types are the same. Double-equals performs the _loose equality_, +meaning it can return `true` even if the values are of different type. +Double-equals may _coerce_ a value into another type for the comparison, and +this behavior is hard to predict: + +```javascript +console.log(5 === "5"); // false +console.log(5 == "5"); // true +console.log(0 === false); // false +console.log(0 == false); //true +``` + +Whoa! Surprised by these results? It can be hard to predict how `==` behaves, so +we will avoid using it in this course and as a best practice. Stick to using +`===` because it respects data types. + +## What you've learned + +- `>`, `<`, `>=`,`<=`, `===`, and `!==` can be used to compare values +- we prefer to use `===` to check for equality because it takes the type into + account. + +________________________________________________________________________________ +# Basic Variables + +Variables are used to store information to be referenced and manipulated in a +computer program. They also provide a way of labeling data with a descriptive +name, so our programs can be understood more clearly by programmers. It is +helpful to think of variables as containers that hold information. Their sole +purpose is to label and store data in computer memory. This data can then be +used and even changed throughout the lifetime of your program. + +When you finish this reading, you should be able to: + +- declare variables using the `let` keyword +- assign values to variables using the assignment operator (`=`) +- use the shortcuts `+=`, `-=`, `++`, `--` to reassign variables +- identify `undefined` as the default value for unassigned variables + +## Initializing a variable + +To initialize a variable in JavaScript we'll need two new pieces of syntax: +`let` and `=`. We can give the variable any name that we wish and assign it a +value. Once we initialize a variable, the variable will evaluate to the value +assigned: + +```javascript +let bootcamp = ""; +console.log(bootcamp); // '' + +let birthYear = 2012; +console.log(birthYear); // 2012 +``` + +**Did you know?** JavaScript variables names can contain any alphanumeric +characters, underscore (\_), or dollar sign (\$). However, they _cannot_ begin +with a number. + +Above are examples of how you'll create variables most of the time, so we'll +grow very familiar with the syntax. As a best practice, we should name our +variables in a way that is descriptive and concise. + +The variable initializations above really consist of two steps: _declaration_ +with `let` and _assignment_ with `=`. Let's break these two steps down. + +### Declaring a variable + +In JavaScript, in order to use a variable, we must _declare_ it. Variable +**declaration** is the act of introducing the variable to the environment. + +To declare a variable, use the `let` keyword, followed by a space and then the +name of the variable. + +```javascript +let bootcamp; +console.log(bootcamp); // undefined +``` + +Once a variable is declared, it will contain `undefined` as it's value. +`undefined` is a common default value in JavaScript, we'll see it come up in a +few different places. You can think of `undefined` as showing that the variable +is empty. + +### Assigning a variable + +Once a variable has been declared, we can assign it a value using single-equals +`=` : + +```javascript +let bootcamp; +console.log(bootcamp); // undefined +bootcamp = ""; +console.log(bootcamp); // '' +``` + +## Manipulating variables + +To change the value of a variable, we need to reassign it to a new value with +`=` : + +```javascript +let num = 42; +console.log(num + 8); // => 50 +console.log(num); // => 42 + +num = num + 10; +console.log(num); // => 52 +``` + +In the code above, `num + 8` will evaluate to `50`, but it will not change the `num` +variable to `50`. If we want to change the `num` variable, we must reassign to +it. + +### Assignment Shorthand + +Changing the value of a number variable is something fairly common in the +programming world. Luckily there is some shorthand operators we can use: + +```javascript +let number = 0; +number += 10; // equivalent to number = number + 10 +number -= 2; // equivalent to number = number - 2 +number /= 4; // equivalent to number = number / 4 +number *= 7; // equivalent to number = number * 7 +console.log(number); // 14 +``` + +We also have other shorthand to add or subtract exactly 1 from a variable, the +increment (`++`) and decrement (`--`) operators: + +```javascript +let year = 3004; +year++; +console.log(year); // 3005 +year--; +console.log(year); // 3004 +``` + +## NaN + +Now that we have the ability to perform arithmetic with variables, let's take a +look at a common programming mistake, getting a result of `NaN` (not a number): + +```javascript +let num; +console.log(num + 3); // NaN +``` + +The above code gives `NaN` because the unassigned `num` variable contains +`undefined`; adding `3` to `undefined` results in `NaN`. In general, any +nonsensical arithmetic will result in `NaN`. Math operations involving +`undefined` is perhaps the most common mistake: + +```javascript +console.log(undefined + 3); // NaN +console.log("fish" * 2); // NaN +``` + +## What you've learned + +- variables are declared with `let` and will contain the value `undefined` by + default +- we can use single-equals `=` to assign variables +- changing a variable requires a reassignment, for which there are many + shortcuts for (`+=`, `-=`, etc.) + +________________________________________________________________________________ +# Introduction to Functions + +We hope you are ready - because you are on the brink of one of the most fun +parts of writing JavaScript: writing **functions**. A function is a procedure of +code that will run when called. We only "write" a function once (**function +declaration**), but we can "use" it as many times as we please (**function +calls**). Functions are the fundamental building blocks of JavaScript and +mastering them is a big step on the road to JavaScript mastery. + +When you finish this reading, you should be able to: + +1. Describe what a function in JavaScript is. +2. Demonstrate how to invoke a function. +3. Write a function using function declaration. +4. Use the `return` keyword to return a value from a function. + +## Writing Functions + +A function is a set procedure of code that will run when called. Functions +really start to make sense when put in the perspective of solving problems. So +for example say you want to find the average of two given numbers. Meaning we +want to take two numbers, add them together then divide by 2: + +```js +> (5 + 5) / 2 +5 + +> (15 + 3) / 2 +9 + +> (7 + 2) / 2 +4.5 +``` + +Writing out the same code again and again gets tedious fast. What you can do +instead is write a new _function_. + +### Function Declaration + +A _function definition_ consists of the function keyword, followed by three +things: + +1. The **name** of the function. +2. A list of _parameters_ to the function, enclosed in parentheses, `()`. +3. The code to be run when this function is run, enclosed in curly + brackets,`{ }`. + +So for our above example of averaging two numbers we could write a function that +would do that for us! We would write something like the following: + +```js +// 1. average is the name of the function +// 2. number1 & number2 are the parameters being passed in +function average(number1, number2) { + // 3. this is the code run every time this function is used + return (number1 + number2) / 2; +} +``` + +First thing to notice for the above `average` function is that we didn't use any +_real_ numbers. You always want to write functions to accept as wide a range of +data as possible. Utilizing the incoming _parameters_ to a function is one of +the keys to making functions flexible. + +In the case of the `average` function, we want to use it to calculate the +average of any two numbers. `number1` and `number2` are the _parameters_ for the +`average` function. In other words, the `average` function expects to be given +two numbers, `number1` and `number2`. We'll be talking a lot more about +parameters later - but for now know that when you define a function with +parameters you are declaring those parameters as usable variables within that +function. + +The beauty of a function is that if we define it in a clever way, it will work +on a whole slew of data! For example, we want `average` to work on any two +numbers, whether or not they are whole numbers, decimal, negative, etc. + +## Invoking or "calling" a function + +Now that we've written a function how do we actually use it? Once defined a +function can be invoked or "called" as many times as we please. + +### Order of code + +Let's step away from `average` for a bit to see how a simple function call +works. Say we run JavaScript code that looks like this: + +```js +console.log("First!"); + +console.log("Second!"); +``` + +Running this code will return exactly as we expect. We will see `First!` printed +out, followed by `Second!`. In other words, JavaScript will evaluate your code +left-to-right and top-to-bottom. Very intuitive! It's exactly how you are +reading these notes right now. + +However, when JavaScript sees a function definition, JavaScript will **not** +evaluate the code inside of the definition. It will only "remember" the code so +we can execute it later. The code below only prints `First!` followed by +`Fourth!`: + +```js +console.log("First!"); + +function callMe() { + console.log("Second!"); + console.log("Third!"); +} + +console.log("Fourth"); + +// when run this code is ran it will print out: +// "First!" +// "Fourth" +``` + +To actually get the code within `callMe` to evaluate, we must _call_ it by using +`callMe()`. The code below will now print out in order: + +```js +function callMe() { + console.log("Second!"); + console.log("Third!"); +} + +console.log("First!"); +// we call the function by adding ending parenthesis +callMe(); +console.log("Fourth!"); + +// when run this code is ran it will print out: +// "First!" +// "Second!" +// "Third!" +// "Fourth" +``` + +Let's say JavaScript is running the file above. Here are the steps it would +take, starting from the tippy top of the code: + +1. JS sees a definition for `callMe`. It will remember this definition in case + we call the function later. It will **not** evaluate the code inside the + function yet. +2. JS prints out `First!` +3. JS sees that we are calling `callMe()`. At this point it will look at the + prior `callMe` definition and run the code inside. It is as if we are + "jumping" to inside the function definition. This means it will print + `Second!` followed by `Third!` +4. JS sees there is no more code to be run inside of `callMe`, so it "jumps" + back to where we originally called `callMe()` +5. JS will continue evaluating in order and print `Fourth!` + +### An average example + +So a declared function is "saved for later use", and will be executed later, +when it is called, also known as being **invoked**. So thinking back to our +average function we can declare the function and then _invoke_ it. + +When we specify what data to use for a function call, we refer to that process +**passing arguments to the function**. + +```js +// this is a function definition +function average(number1, number2) { + return (number1 + number2) / 2; +} + +// this is a function call with the arguments being 15 & 3 +> average(15, 3) +9 + +// this is a function call with the arguments being 5 & 5 +> average(10, 5) +7.5 +``` + +When we call the function `average(15, 3)`, we run the code inside the +_definition_ for `average`. That is, we plug in the parameters with real numbers +(`number1` becomes `10` and `number2` becomes 16). Think of `number1` and +`number2` as _variables_ that contain the values we pass in when we called the +function. Then we proceed by running the code inside the function. The parameter +names `number1` and `number2` used through the body of the function and behave +like variables. + +## Returning a value + +Now that we know how functions are declared and invoked let's talk about the +inside of the function. We'll start with a statement: _Every function in +JavaScript returns `undefined` unless otherwise specified._ + +Now what does that mean? We'll start with a simple example: + +```js +function sayNumber(number) { + console.log(number); +} + +> sayNumber(1); // prints 1 +1 +undefined +``` + +So what happened there? Let's do a quick step by step: + +1. We declared the `sayNumber` function +2. `sayNumber` was called handing in the argument of 1 +3. The `number` parameter is printed to the console +4. Then the function ends without encountering a `return` statement. Since + nothing was specifically returned then the function returned the default + value for a function which is `undefined`. + +Now let's change our above example to use the keyword `return` to return a +value: + +```js +function sayNumber(number) { + console.log(number); + return true; +} + +> sayNumber(1); +1 // sayNumber still prints 1 +true // but now sayNumber returns as true +``` + +Let's go back to our previous `average` function and talk about the `return` we +used there: + +```js +function average(number1, number2) { + return (number1 + number2) / 2; +} + +// the function call for average(10, 16) will return 13 +// so the result variable will be set to 13 +let result = average(10, 16); + +// if we want to check what a function returns we can do this: +console.log(result); // prints `13` + +// we could alternatively do this: +console.log(average(10, 16)); +``` + +When we _call_ a function, we jump to the function definition and run the code +inside. When we hit a `return` statement, we immediately **exit** the function, +jump back to where we _called_ the function, and evaluate the function call to +the value it _returned_. + +**Every function call evaluates to it's return value!** In other words, the +expression `average(10, 16)` evaluates to `13` just like how the expression +`1 + 1` evaluates to `2`. + +Another important rule of the return statement is that it stops function +execution immediately. This means that any code after a `return` will not be +executed! + +```js +function average(number1, number2) { + let sum = number1 + number2; + return sum; + // anything under the first return will not be executed + console.log("this will not run") + return false; +} + + // when the first return is encountered the entire function will return a value +> average(2, 7); +9 +``` + +So the three things to remember about return statements is: + +1. Every function call evaluates to it's return value. +2. Every function in JavaScript returns `undefined` unless a `return` is + specified +3. Once a `return` statement is encountered the function will immediately stop + and return the value, ignoring any code below the `return` statement. + +## The importance of naming + +A quick but very important side note about good naming. Take this to heart right +now: **Good names are important**. Do yourself, and every other programmer +reading your code, a favor by always using significant function and variable +names. + +For example, `x` is a very non-descriptive name for a variable or function. As +we tackle more complicated problems and our code grows to be more complex, we +are likely to forget what badly named variables originally stood for and what +their purpose was. Non-descriptive names make our code error-prone. **Great code +reads like English and almost explains itself.** As programmers, our goal is to +write code that is not only "correct", but also elegant, readable, and +maintainable! Hold yourself to this high standard. + +As far as syntax goes in JavaScript we always name our functions and variables +`camelCase` for multiple words. (Ex: `tipCalculator`, `currentNumber`, +`puppyPartyFinder`). Other languages use other conventions so it's best to pick +up the standard for your chosen language and stick with it. + +## Review + +By writing a function we can reuse code over and over again to solve similar +problems with different input data (arguments). This will make your life easier +and allow you to start working on more complex problems. + +This reading covered: + +- How to define and invoke a function in JavaScript. +- How to use the `return` keyword to return a value from a function. +- Writing readable JavaScript code by using significant names and following + `camelCase` conventions for multiple word variables and functions + +________________________________________________________________________________ +# Parameters and Arguments + +When talking about functions one of the first things we mentioned was the word +_parameters_. In this reading we will be covering what exactly a parameter is - +as well as the differentiation between _parameters_ and _arguments_. + +When you finish this reading, you should be able to: + +1. Identify the difference between parameters and arguments. +2. Write a function that utilizes declared parameters. +3. Invoking a function with passed in arguments. + +## The difference between Parameters and Arguments + +Let's start off by talking about the difference between _arguments_ and +_parameters_ and how to identify which is which. + +1. **Parameters** are comma separated variables specified as part of a + function's declaration. +2. **Arguments** are values passed to the function when it is invoked. + +So by defining _parameters_ when we declare our function we are effectively +setting accessible variables within the function: + +```js +function add(firstParameter, secondParameter) { + console.log(firstParameter + secondParameter); +} + +// the add function declares two parameters +> add(1, 2); //=> 3 +``` + +In the above example we declared our parameters when we declared our function. +Now _arguments_ work slightly differently - when the function is invoked we are +passing in _arguments_. So in the above example when we invoked `add(1, 2)` the +`(1,2)` were the _arguments_ being passed in. So when a function is invoked the +value of the declared parameters is assigned to the passed in _arguments_. + +You can think of it _parameters_ and _arguments_ like a recipe. A recipe is a +list of ingredients (_parameters_) and list of steps (the code to be run). When +someone cooks the recipe (_invokes_ the function) they add the ingredients they +actually have(_arguments_). The result of cooking the recipe is the delicious +`return` value! + +### Extra arguments + +In JavaScript a function will not throw an error if the number of _arguments_ +passed during a function invocation is different than the number of parameters +listed during function declaration. This is very important to know! + +Let's use the above function to demonstrate: + +```js +function add(firstParameter, secondParameter) { + console.log(firstParameter + secondParameter); +} + +// this will ignore the 17 & 14 +// the first two arguments passed in will be assigned to the first two parameters +> add(1, 2, 17, 14); //=> 3 +``` + +Notice in the above example we passed in 4 arguments (1, 2, 17, 14) to `add`. +Since the function was only looking for two parameters that is all it uses. + +### Not enough arguments + +Now what happens if we pass in less arguments then needed? + +```js +function add(firstParameter, secondParameter) { + console.log(firstParameter + secondParameter); +} + +> add(5); //=> NaN +``` + +Whoa what happened there? Let's do a play-by-play: + +1. `firstParameter` was set to equal the first passed in argument which in the + above case is 5. +2. Since there is no second argument then `secondParameter` is declared as a + variable but is set to the default value of `undefined`. +3. The function then tries to add 5 to `undefined` which is definitely not a + number! So we get `NaN` (which means `Not A Number`) printed to the console. + +As you write more functions you'll grow very comfortable using both arguments +and parameters to accomplish your function's goal. + +## Review + +- Parameters are variables defined as a part of a function's declaration. +- Arguments are values passed to the function when it is invoked. +- JavaScript functions can intake a different number of arguments than the + number of parameters listed during function declaration. + +________________________________________________________________________________ +# WEEK-01 DAY-2
*Control Flow* {ignore=true} +________________________________________________________________________________ +# Control Flow and Array Learning Objectives + +Below is a complete list of the terminal learning objectives for this lesson. +When you complete this lesson, you should be able to perform each of the +following objectives. These objectives capture how you may be evaluated on the +assessment for this lesson. + +1. Define a function that accepts a sentence string and two words as args. The + function should return a boolean indicating if the sentence includes either + word. +2. Identify a pair of mutually exclusive conditions +3. Given a for loop, translate it into a while loop, and vice-versa +4. Write a function that iterates through a provided string argument +5. Given a description of pig latin, write a function that takes in a string + argument and utilizes String#slice to translate the string into pig latin. +6. Write a function that takes in an array of words and a string as arguments + and returns a boolean indicating whether the string is located inside of the + array. The function must use Array#indexOf. +7. Define that an array literal is an ordered list of values defined by using + bracket and individual values are read by indexing. +8. Prevent code that can throw an exception from causing the program to crash. the terminal learning objectives for this lesson. +When you complete this lesson, you should be able to perform each of the +following objectives. These objectives capture how you may be evaluated on the +assessment for this lesson. + +1. Define a function that accepts a sentence string and two words as args. The + function should return a boolean indicating if the sentence includes either + word. +2. Identify a pair of mutually exclusive conditions +3. Given a for loop, translate it into a while loop, and vice-versa +4. Write a function that iterates through a provided string argument +5. Given a description of pig latin, write a function that takes in a string + argument and utilizes String#slice to translate the string into pig latin. +6. Write a function that takes in an array of words and a string as arguments + and returns a boolean indicating whether the string is located inside of the + array. The function must use Array#indexOf. +7. Define that an array literal is an ordered list of values defined by using + bracket and individual values are read by indexing. +8. Prevent code that can throw an exception from causing the program to crash. + +________________________________________________________________________________ +# Control Flow - Conditional Statements + +So far the code you've written has been pretty direct in it's intent. You can +define functions and variables but, so far the functions you've created haven't +been able to do that much for you _yet_. It's time to start writing functions +that can do things _conditionally_ by utilizing _control flow_. + +In simple terms - **control flow** is the order in which instructions are +executed within a program. One modifies control flow using _control structures_, +expressions that alter the control flow based on given parameters. The control +structures within JavaScript allow the program flow to change within a unit of +code or a function. + +This reading will be covering one of the two main _control structures_ you +will use time and time again - _Conditional statements_. _Conditional +statements_ are used to perform different actions based on different conditions. + +When you finish this reading, you should be able to: + +- Write `if`, `else if`, `if...else` conditional statements. +- Know that conditional statements can have only one `if` and one `else` + statement. +- Identify that conditional statements can be nested. + +## A Quick Word on Syntax + +Before we get started we'll quickly go over the terms we'll be using to +represent syntax. + +1. `[ ]` are square **brackets** +2. `{ }` are curly **braces** +3. `( )` are **parentheses** + +## Writing Conditional Statements + +Conditional Statements are the second fundamental _control structure_ for +writing JavaScript and are pretty straight forward. The simplest conditional +statement is the `if` statement. An `if` statement has two parts, the _test +expression_ (the code that immediately follows the `if` which goes in +parentheses), and the _then expression_ (this code belongs in braces after the +`if` expression). The _then_ expression will only run when the `if` expression +is truthy. + +Here is an example of a simple `if` statement: + +```js +// this is the test expression +if (3 === 3) { + // this is the then expression + // this code will run if the above statement is true + console.log("this is a three!"); +} +``` + +The `if` statement above allows you to specify what should happen if your +particular expression evaluates to true. You can chain additional _test +expressions_ onto this `if` statement by using a `else if` statement. + +The syntax for `else if` is very similar as an `if` statement: + +```js +function mathFun() { + let x = 2 + 3; + + if (x === 3) { + console.log("we have a 3"); + } else if (x === 4) { + // this code will run if the above statement is true + console.log("we have a 4"); + } else if (x === 5) { + // this code will run if the above statement is true + console.log("we have a 5"); + } +}; + +mathFun(); // => "we have a 5" +``` + +The `else if` and `if` statements do not, however, provide the option to specify +something else that should happen in the event that all of the above expressions +evaluate to be `falsey`. The `if...else` statement reads just like English. The +JS interpreter will execute the `else` statement if all the above conditions +given are `falsey`. See below for an example: + +```js +function mathFun() { + let x = 19; + if (x === 3) { + console.log("we have a 3"); + } else if (x === 4) { + console.log("we have a 4"); + } else { + console.log("I will return if everything above me is falsey!"); + } +}; + +mathFun(); // => "I will return if everything above me is falsey!" +``` + +You can chain an arbitrary number of `else if` statements but there can only be +one `if` statement and one optional `else` statement. The `if` introduces the control +structure and the `else` acts as a fail safe to catch everything that didn't +meet the above conditions. + +Only one _then expression_ is ever executed in an `if`, `if...else`, or +`if...else` statement. If one of the _test expressions_ is truthy, then the +result of its _then expression_ is the result of the **entire** conditional +statement: + +```js +let x = 3; +if (x === 3) { + console.log("this will run"); +} else { + console.log("this will not run"); +} +``` + +Additionally, you can nest conditional statements within each other but it will +get hard to read pretty quickly and is discouraged: + +```js +function mathFun(x) { + if (x === "math") { + if (x === "math" && x[0] === "m") { + if (x[1] === "a") { + console.log("this got confusing fast"); + } else { + console.log("that is not math!"); + } + } else { + console.log("that is for sure not math!"); + } + } else { + console.log("I will return if everything above me is false!"); + } +}; + +mathFun("math"); // => "this got confusing fast" +``` + +## Review + +- Conditional statements allow us to control what actions should be taken based + on a boolean (truthy or falsey) expression +- In a chain of _then expressions_ (`if...else if...else`), only one of the + _then expressions_ will be executed. +- Conditional statements can have only one `if` and one `else` statement. +- Conditional statements can be nested. + +________________________________________________________________________________ +# Mutually Exclusive Conditions + +You have now learned how to write conditional statements. Now we'll talk a +little bit more about how to write them using best practices. + +When you finish this reading, you should be able to: + +- Identify a pair of mutually exclusive conditions. + +## When to use if statements + +Say you are given the challenge to write a function that that will call another +function named `bigNumber` if the given argument is **greater** than 100 or call +a function named `smallNumber` if it the given argument is smaller. You could +write a function to do that which would look like this: + +```js +function numberSeparator(number) { + if (number < 100) { + // number is smaller than 100 so we invoke smallNumber + smallNumber(); + } + if (number === 100) { + // number is equal to 100 so we invoke smallNumber + smallNumber(); + } + if (number > 100) { + // number is larger than 100 so we invoke bigNumber + bigNumber(); + } +} +``` + +As you can probably tell the above function uses a lot of code to do a simple +task. To be clear the function above would work for our aim - but it repeats +itself. There is an age old principal for writing good code named **DRY** or +**Don't repeat yourself**. As good programmers we always want our code to be +clear, concise, and efficient. + +A general rule of thumb is that if you are working with a condition that is +**mutually exclusive**, meaning if one condition is true the other condition +must be false, then you should use an `if/else` statement. You can also think of +**mutually exclusivity** like a coin flip - it can be either heads or tails but +not both. + +Going back to the original problem at hand we can see it makes intuitive sense +with the way the challenge is phrased: If the number is larger than 100 then +we'll call `bigNumber`, otherwise we invoke is `smallNumber`. + +So let's rewrite the above function to read a little more clearly: + +```js +function numberSeparator(number) { + if (number > 100) { + bigNumber(); + } else { + smallNumber(); + } +} + +// this also works +function numberSeparator(number) { + if (number <= 100) { + smallNumber(); + } else { + bigNumber(); + } +} +``` + +Look at how much clearer that is! Writing good code is an art - devote yourself +to becoming an artist! + +## Review + +- How to identify a pair of mutually exclusive conditions. +- DRY - don't repeat yourself! + +________________________________________________________________________________ +# Control Flow - Looping + +A quick reminder before we start - **control flow** is the order in which +instructions are executed within a program. One modifies control flow using +_control structures_, expressions that alter the control flow based on given +parameters. This reading will be covering the second of the main _control +structures_ you will use time and time again - _loops_. + +When you finish this reading, you should be able to: + +1. Know how to write a `while` loop and a `for` loop. + - Know how to convert a `for` loop into a `while` loop +2. Know that index variables conventionally start at zero. +3. Explain what an _iteration_ is. + +## Looping + +Imagine you are at a friend's house and your friend has six dogs. Someone left +the back gate open and all the dogs go out in the yard and get super muddy. Now +your friend wants to clean their dogs but they only have one bathtub! You can't +wash all the dogs at once. So the only option is to give the dogs a bath one at +a time until they are all clean. When you start 0 dogs are clean and 6 dogs are +dirty. + +_While_ there are still dirty dogs you still have a job to do. That is your +**condition** - you will stop giving baths once all 6 dogs are clean. So after +one bath you you have 1 clean dog and 5 dirty dogs. You've +_incremented_(increased by one) your number of clean dogs. After each bath you +check your **condition** again until you have 6 clean dogs so you know you can +stop! + +What we've described above is the idea of looping - setting a condition, +executing an action, doing something to make sure our condition will be met +eventually, and rechecking our condition before executing our next action. + +Loops are a fundamental _control structure_ for writing JavaScript. +Loops will repeatedly execute a section of code while a condition is true. Loops +are simple to write and incredibly powerful! There are many variations of loop +but we will be covering the two most fundamental loops now - **while** loops and +**for** loops. + +### While Loops + +One of the simplest loops in `JavaScript` is the `while` loop. As with all +loops, the `while` loop will execute a block of code as long as a specified +condition is true. The while loop starts with the keyword `while` then states a +condition in parentheses. The code in the following braces will be run until the +above condition is met. + +```js +while (condition) { + // code block to be executed +} +``` + +In the following example, the code in the loop will run, over and over again, as +long as a variable (`index`) is less than 10: + +```js +let index = 0; + +// this is the condition that will be checked every time this loop is run +while (index < 10) { + console.log("The number is " + index); + // this is common shorthand for index = index + 1 + index++; +} +``` + +The most important thing to remember when writing any loop is to always be +working towards your condition. In the example above if we did not increment the +`index` variable by 1 each time the loop ran then we would be stuck with what we +call an **infinite loop**: + +```js +let index = 0; + +// this is an infinite loop because our condition will never be met +while (index < 10) { + console.log("The number is " + index); + // if we do not increase the index then our condition is never met + // Meaning this will run forever! +} +``` + +The above code will run until whatever interpreter you are using crashes. + +### Important Loop Knowledge + +A quick word before we learn about the next loop. + +The _index_ is the traditional word for the variable that keeps track of how +many times the loop has been run. Don't write loops with indices starting at +one; you'll confuse other programmers and yourself. Indices have started at zero +for a long time, and for good reason. It's much easier to use loops that start +with an index of zero because Array and String indices also start at zero. + +```js +let array = [0, 1, 2]; +let index = 0; + +while (index < array.length) { + console.log( + "Both the index and the current array position are " + array[index] + ); + index++; +} +``` + +In the above code we will do one loop for each digit in the Array above. We call +each of those loops an "iteration". An iteration is the act of repeating a +procedure, hence looping is an **iterative** technique. Each repetition itself +is also called an "iteration." So you can use loops to _iterate_ through Arrays +and Strings. + +### For Loops + +A `for` loop can be broken down into three sections: + +1. The _initial expression_ which will be run once at the beginning of the loop. +2. The _condition_ which is checked every time the loop is run. If this + condition is true the loop will run again. If this condition is false the + loop will end. +3. The _loopEnd expression_ which will be run at the end of the loop before + checking the _condition_ again. + +```js +for (;;) +``` + +The `for` loop is usually used with an integer counter: + +```js +for (let index = 0; index < 10; index += 1) { + // the code inside this block will run 10 times +} +``` + +While the _loopEnd expression_ is normally used to increase a variable by one +per loop iteration, it can contain any statement, such as one that decreasing +the counter, or increasing it by 2. + +You can use the `for` loop to iterate through all kinds of things. Check out the +example below for how to iterate through a String: + +```js +let testString = "testing"; + +// we can use the testString's length as our condition! +// Since we know the testString's index starts at 0 +// and our index starts at 0 we can access each letter: +for (let index = 0; index < testString.length; index += 1) { + let letter = testString[index]; + console.log(letter); +} +``` + +These are the most basic types of loops. If all else fails, you can always fall +back on these two loops. All the other loop forms are just more convenient forms +of these basic loop styles. + +## Translating From One Loop to Another + +So far we have covered both `while` and `for` loops. Once you understand the +concept of looping it's easy to translate one loop to another: + +```js +// these two do the exact same thing! +function forLoopDoubler (array) { + // it is convention to shorten index to just i in most cases + for (let i = 0; i < array.length; i++) { + array[i] = array[i] * 2; + } + return array; +}; + +function forLoopDoubler (array) { + let i = 0; + while (i < array.length) { + array[i] = array[i] * 2; + i++; + } + return array; +}; + +forLoopDoubler([1, 2, 3]); // => [2,4,6] +whileLoopDoubler([1, 2, 3]); //=> [2,4,6] +``` + +## Review + +- We can use a `for` or `while` loop to repeat a block of code repeatedly. +- While the loop condition is true, we will execute another iteration of the + loop. +- When the loop condition is false, we will exit the loop. + +________________________________________________________________________________ +# The Array Type + +This reading will be about one of JavaScript's global objects, the **Array** +type. JavaScript arrays are used to store multiple values all within a single +structure, much like a creating a list. Arrays can hold strings, integers and +even other arrays! Arrays are incredibly useful for holding a bunch of different +information all in one place. + +When you finish this reading, you should be able to: + +- Write arrays using correct syntax +- Identify that an array is an ordered list of values defined by using brackets +- Use `.length` to obtain a count of the numbers of elements that comprise an + array +- Index an array to refer to a single value +- Concatenate multiple arrays together + +## Using arrays + +While coding you will find that you often find yourself needing to refer to a +bunch of data at once. For instance, what if you wanted to refer to the entire +English alphabet. Sure, you could create a bunch variables for each letter in +the alphabet: + +```js +let a = "a"; +let b = "b"; +let c = "c"; +let d = "d"; +// and so on for way too long... +``` + +However this becomes cumbersome and unmanageable quickly. An Array is a data +structure that solves this problem. Arrays are always wrapped in square +brackets, `[]`, and store their comma separated values in sequential order. +Arrays in JavaScript are also very flexible: we can put elements into an array, +replace elements in an array, and remove elements from the array. + +So going back to our first example of containing the alphabet: + +```js +let alphabet = [ + "a", "b", "c", "d", "e", "f", + "g", "h", "i", "j", "k", "l", + "m", "n", "o", "p", "q", "r", + "s", "t", "u", "v", "w", "x", + "y", "z" +]; +``` + +## Indexing arrays + +### Calculating the length of an array + +Since an array can container any number of values you will find it useful to +count the number of values available to you using `.length`: + +```js +console.log([4, 7, 9].length); // => 3 +console.log([1, 2].length); // => 2 +console.log([].length); // => 0 +``` + +### Properly indexing an array + +Arrays consist of multiple values all stored in sequential order. These value +are numbered by **indices** starting at 0 (just like indexing a string!). So +given the below example: + +```js +let numbersAndLetters = ["b", "z", 17, "cat"]; +``` + +In the above `numbersAndLetters` array if we access `numbersAndLetters` at the +index of 0 we get back the value of "b". If we access `numbersAndLetters` at the +index of 1 we get "z", at the index of 3 we get 17, etc. We can specify which +value we'd like to access in an array by using square brackets,`[]`, and +specifying an index: + +```js +console.log(numbersAndLetters[0]); // => "b" +console.log(numbersAndLetters[1]); // => "z" +console.log(numbersAndLetters[2]); // => 17 +console.log(numbersAndLetters[3]); // => "cat" +``` + +Notice that even though the index at `numbersAndLetters[3]` has the value of a +string with multiple characters ("cat") we return the _entire value_ listed at +that index. + +**Reminder:** Arrays **always** start at the index of 0, not 1. This is the +convention in programming. Additionally, indices should always be a number. + +We can access a value in an array directly by providing an index for the value +we'd like to access in that array (`array[index]`). See below for an example: + +```js +console.log(["a", "b", "c"][0]); // => "a" +console.log(["a", "b", "c"][1]); // => "b" +console.log(["a", "b", "c"][2]); // => "c" +console.log(["a", "b", "c"][3]); // => `undefined` +``` + +As we see in the code above, if we try to access an element at an index that is +not inside the array, we get back `undefined`. This makes sense because there is +no value at that given position! + +### The classic "off by one" error + +Arrays are similar to strings in that both of their indices start at 0 instead +of 1. Forgetting this fact can lead to some pretty confusing situations. Let's +focus on an important distinction: the index of the last value of an array is +always one less than its length. + +```javascript +console.log([4, 7, 9].length); // => 3 +console.log([4, 7, 9][3]); // => undefined +console.log([4, 7, 9][2]); // => 9 +``` + +In other words, although the `length` of `[4, 7, 9]` is 3, the index of the last +value (`9`) is 2. A good rule of thumb of accessing the last index of an array +is to find the length and then subtract one: + +```js +let testArray = [4, 7, 9]; +let finalIndex = testArray.length - 1; // => (3 - 1) = 2 +console.log(testArray[finalIndex]); // => 9 +``` + +## Working with arrays + +### Containing data in arrays + +By packaging groups of related data into a single array, we gain the added +benefit of being able to refer to that data as a single collection. Arrays don't +have to just hold single characters- they are capable of holding entire strings, +numbers, and even other arrays! + +```js +let wackyArray = [2, 17, "apple", "cat", ["apple"]]; + +console.log(wackyArray[0]); // => 2 +console.log(wackyArray[1]); // => 17 +console.log(wackyArray[3]); // => "cat" +console.log(wackyArray[4]); // => ["apple"] +``` + +Just think of all the possibilities of what you can store in a single array! +However, just because you can _doesn't_ mean you should. In practice we will +almost always be storing similar kinds of data, that are coming from a common +source (i.e. items in a shopping list, ID numbers, tasks on a todo list). + +### Using indexOf with arrays + +We can also calculate the index of a given value within an array by using +`indexOf`: + +```javascript +console.log([1, 3, 5, "apple", "jet"].indexOf(3)); // => 1 +console.log([1, 3, 5, "apple", "jet"].indexOf(5)); // => 2 +console.log([1, 3, 5, "apple", "jet"].indexOf("jet")); // => 4 + +// this won't be found in the array +console.log([1, 3, 5, "apple", "jet"].indexOf("potato")); // => -1 +``` + +If we attempt to search for a value that is **not** present in an array, +`indexOf` will return -1. This makes sense because we know that -1 is not a +valid array index. The smallest index possible is 0! + +## Concatenation with arrays + +As a reminder, concatenation is just a fancy word for joining things together +into a single collection. Now, this is where arrays will differ from strings. +The `+` operator only exists for numbers and strings. If you try to use the `+` +on an array it will try to help you out by _converting your arrays into +strings_. + +```js +console.log([1, 2, 3] + [4, 5, 6]); // => 1,2,34,5,6 +``` + +JavaScript was just trying to help! However that is probably not what you meant +to do. Good thing JavaScript has a seperate method for putting two array +together. To concatenate arrays, we can use the aptly named `.concat` method: + +```javascript +console.log([1, 2, 3].concat([4, 5, 6])); // => [1, 2, 3, 4, 5, 6] +``` + +## What you've learned + +- An **Array** is a data type that contains a list of in order values surrounded + in square brackets `[]`. +- `array.length` returns the number of values in the `array`. +- Each value of an array is associated with a number index; the first value of + an array is at the index of 0. +- We can use `array.indexOf(value)` to obtain the index of `value` within + `array`; if `value` is not found, then -1 is returned. +- We can use `.concat` to concatenate multiple arrays, combining them into a + single array. + +________________________________________________________________________________ +# WEEK-01 DAY-3
*Intermediate Functions* {ignore=true} +________________________________________________________________________________ +# Intermediate Functions Learning Objectives + +Below is a complete list of the terminal learning objectives across all +"Intermediate Function" lessons. When you complete these lessons, you should be +able to perform each of the following objectives. These objectives capture how +you may be evaluated on the assessment for these lessons. + +1. Identify that strings are immutable and arrays are mutable +2. Define a function using both function declaration and function expression + syntax +3. Utilize Array#push, #pop, #shift, #unshift to mutate an array +4. List the arguments that can be used with Array#splice +5. Write a function that sums up elements of an array, given an array of numbers + as an argument +6. Utilize Array#forEach, #map, #filter, #reduce in a function +7. Define a function that takes in an array of numbers and returns a new array + containing only the primes +8. Define a function that takes in a 2D array of numbers and returns the total + sum of all elements in the array +9. Define a function that takes in an array of elements and returns a 2d array + where the subarrays represent unique pairs of elements +10. Define a function that takes in an array of numbers as an argument and + returns the smallest value in the array; if the array is empty return null the terminal learning objectives across all +"Intermediate Function" lessons. When you complete these lessons, you should be +able to perform each of the following objectives. These objectives capture how +you may be evaluated on the assessment for these lessons. + +1. Identify that strings are immutable and arrays are mutable +2. Define a function using both function declaration and function expression + syntax +3. Utilize Array#push, #pop, #shift, #unshift to mutate an array +4. List the arguments that can be used with Array#splice +5. Write a function that sums up elements of an array, given an array of numbers + as an argument +6. Utilize Array#forEach, #map, #filter, #reduce in a function +7. Define a function that takes in an array of numbers and returns a new array + containing only the primes +8. Define a function that takes in a 2D array of numbers and returns the total + sum of all elements in the array +9. Define a function that takes in an array of elements and returns a 2d array + where the subarrays represent unique pairs of elements +10. Define a function that takes in an array of numbers as an argument and + returns the smallest value in the array; if the array is empty return null + +________________________________________________________________________________ +# Function Expressions + +You may have noticed that we've been writing many functions so far in the +course! We will continue to do so since functions are the building blocks of the +eventual applications that we will build. That being said, let's begin to +broaden the way we think about functions. In particular, we'll want think of +functions as expressions that we can store in variables - just like our classic +data types of number, string, boolean, array, and object! + +When you finish this article, you should be able to: + +- identify functions as first-class objects in JavaScript +- define a function using function expression syntax + +## Functions as first-class objects + +JavaScript is well known for being a programming language that treats functions +as "first-class objects". This fancy talk means that you can treat a function as +a "normal" value by storing it in a variable. We'll leverage this key concept in +very clever ways later in the course. For now, let's begin with a simple example +that shows the "first-class object" nature of functions: + +```javascript +let calculateAverage = function(a, b) { + return (a + b) / 2; +}; + +console.log(calculateAverage(10, 20)); // 15 +``` + +In the code snippet above, we define the `calculateAverage` by assigning a +variable to contain the function's definition. By doing this, the variable's +name is effectively the function's name. So to call the function, we simply +refer to the variable name. Note that we do not write the function's name after +the `function` keyword, where we normally would. We will refer to this new way +of defining functions as _function expression syntax_ and the classic way of +defining functions as _function declaration syntax_. In general, we can define +functions using either syntax: + +```javascript +// function declaration syntax +function myFunctionName(arg1, arg2) {} + +// function expression syntax +let myFunctionName = function(arg1, arg2) {}; +``` + +In the coming sections, we'll highlight moments when we'll prefer one syntax +over the other. For now, get acquainted with the new syntax as it is something +you'll be seeing a lot of as a programmer! + +### A peek under the hood + +Perhaps you're finding it tough to understand what it means for a variable to +contain a function - it is indeed a very abstract idea for new programmers. +Let's draw a comparison. We know that when we assign an expression to variable, +the expression first evaluates to a single value, which we then store in the +variable name: + +```javascript +let myNum = 4 + 4; +console.log(myNum); // prints 8 +console.log(myNum * 3); // prints 24 +``` + +In the same way we can treat a function definition as an expression that +evaluates! + +```javascript +let myFunc = function() { + console.log("I'm a function"); +}; + +console.log(myFunc); // prints [Function: myFunc] +myFunc(); // prints "I'm a function" +``` + +Looking at the snippet immediately above, you'll notice that when we print the +`myFunc` variable directly, without calling the function with parentheses, +JavaScript simply says the variable contains a function named myFunc +(`[Function: myFunc]`). You can truly imagine a function as a value that we can +store and use as we please. + +> The term _anonymous function_ may also be used to describe a function +> expression before it is assigned to any variable. Following the example above, +> we'll use the word _anonymous function_ to describe the function expression +> _before_ the assignment to the `myFunc` variable is complete. Once the +> assignment is complete, it would be silly to refer to `myFunc` as an +> `anonymous function` because an _anonymous function_ has no name. + +## What you've learned + +- functions can be stored in variables; just like any other values in + JavaScript! + +________________________________________________________________________________ +# Two-Dimensional Arrays (2D Arrays) + +Time to broaden our understanding of arrays! We've already explore the +fundamentals of arrays. Mainly, we can store any type of data we please as +elements of an array and even mix types together. However, what happens if we +store an array as an element of an array? + +When you finish this article, you should be able to: + +- index into the inner elements of a 2D array +- use nested loops to iterate through a 2D array + +## Multidimensional Arrays + +When we store arrays as elements of other arrays, we refer to those structures +as multidimensional arrays. If the "depth" of the nested arrays is at exactly 2 (an +outer array containing inner arrays), then we'll refer to it as a +two-dimensional array: + +```javascript +let twoDimensional = [["a", "b", "c"], ["d", "e"], ["f", "g", "h"]]; + +console.log(twoDimensional[1]); // [ 'd', 'e' ] +console.log(twoDimensional[1][0]); // 'd' + +let subArr = twoDimensional[1]; +console.log(subArr[0]); // 'd' +``` + +Note that indexing the outer `twoDimensional` array will return an element like +usual, it's just that element happens to be another array. To gain access to the +innermost elements, we simply need to apply another set of indexing brackets! + +If we style our 2D arrays nicely so that each subarray is on a new line, we can +interpret the double indices as `[row][column]`: + +```javascript +let twoDimensional = [ + ["a", "b", "c"], + ["d", "e"], + ["f", "g", "h"]]; + +// get the element in the 0th row, 2nd col: +console.log(twoDimensional[0][2]); // 'c' +``` + +## Iterating through 2D Arrays + +Since a 2D array is just an array of arrays. We'll need to use a loop within a +loop to iterate through a 2D array: + +```javascript +let array = [["a", "b", "c"], ["d", "e"], ["f", "g", "h"]]; + +for (let i = 0; i < array.length; i++) { + let subArray = array[i]; + console.log(subArray); + + for (let j = 0; j < subArray.length; j++) { + console.log(subArray[j]); + } +} +``` + +In the nested loops above, the `i` index refers to the current "row" and the `j` +index refers to the current "column". It's worth noting that since the inner +subArrays have different length, we'll want to specifically reference the length +of that subarray in our inner loop condition `j < subArray.length`. The code +above will print: + +```plaintext +[ 'a', 'b', 'c' ] +a +b +c +[ 'd', 'e' ] +d +e +[ 'f', 'g', 'h' ] +f +g +h +``` + +## When is a 2D array practical? + +As a preview of things to come let's briefly mention when you'll find a 2D array +useful in your future projects. Imagine how'd you represent a "grid": + +- tic-tac-toe (3x3 grid) +- chess (8x8 grid) +- sudoku (9x9 grid) +- excel (a sheet is an arbitrarily sized 2D array) + +## What you've learned + +- an array can contain arrays as elements, we call this a 2D arrays +- to iterate through a 2D array, used nested loops + +________________________________________________________________________________ +# Mutability in JavaScript + +So far in the course we've explored a handful of methods that manipulate data. +We'll be growing our arsenal of methods further overtime, so we'll want to gain +awareness for **exactly** how we should expect these methods to manipulate the +data we give them. To this end, let's analyze which methods will modify existing +data and which methods do not. We refer to this concept as **mutability**. + +When you finish this article, you should be able to: + +- Explain what "mutability" is +- Correctly label JavaScript data types as immutable or mutable + +## What is mutability? + +At its face value, _mutability_ is a simple concept. You may be familiar with +the word _mutation_, which refers to a alteration (usually in DNA). Something +that is _mutable_ can be changed, while something that is _immutable_ is +unchanging and permanent. To illustrate this concept, we'll begin with strings +and arrays. We've spent some time with these two data types and by now we +recognize that the two types share many similarities. Both have indices, +`length`, and even share common methods like `slice`. However, they differ +greatly in their mutability: + +```javascript +let myArr = ["b", "e", "a", "m"]; +myArr[0] = "s"; +console.log(myArr); // 'seam' + +let myStr = "beam"; +myStr[0] = "s"; +console.log(myStr); // 'beam' +``` + +Above we have shown that we can assign a new element to an index of an array, +but we cannot assign a new character to an index of a string. In other words, +arrays are _mutable_, but strings are _immutable_. + +An implication of this discovery is that there are _some_ array methods that +will modify an existing array but _zero_ methods that will modify an existing +string. Methods that manipulate string data typically return a _new_ string and +never modify an existing one. A prime example is `toUpperCase`: + +```javascript +let word = "piñata"; +let newWord = word.toUpperCase(); +console.log(word); // 'piñata' +console.log(newWord); // 'PIÑATA' +``` + +Above, notice that the `toUpperCase` method returns a capitalized version of the +string, but does not change the original string. It's also worth noting that not +every array method will mutate. For example, the `slice` method does not mutate +for both strings and arrays. As we learn about methods in the future, we'll be +certain to note what mutates and what does not. + +## Mutable or immutable, that is the question + +Now that we have a grasp of _mutability_, let's take inventory and identify +JavaScript's data types as mutable or immutable. + +**Mutable** + +- array +- object (we'll learn these soon) + +**Immutable** + +- number +- string +- boolean + +A quick way to remember the above list is to identify that the composite types +(the types that can contain multiple values) of array and object are mutable. +The remaining "simpler" types of number, string, and boolean are immutable. + +## The mutability misconception + +Maybe you are having a tough time believing what we have just claimed. We don't +blame you, you've probably heard the saying that change is the only constant in +the universe. Let's debunk a common argument to turn you into a believer. The +skeptical programmer may use this as an argument to show that numbers are +mutable: + +```javascript +let myNum = 42; +myNum += 8; +console.log(myNum); // 50 +``` + +Because the `myNum` variable now contains `50` where it once contained `42`, it +may seem we have mutated the number, but this is not truly the case. Recall that +`myNum += 8` is shorthand for `myNum = myNum + 8`. Since the right hand side of +the assignment evaluates first, we are simply taking the new number of `50` and +reassigning it to the `myNum` variable. This reassignment of a variable name is +not a mutation of the original number. + +## What you've learned + +- data types that can be changed are mutable, those that cannot be changed are + immutable +- arrays and objects are mutable +- numbers, strings, and booleans are immutable + +________________________________________________________________________________ +# Array Splice + +Time to a learn yet another array method! The [Array#splice][mdn-splice] method +deserves its own reading because of how versatile it is. Feel free to use this +article as a quick reference; let's jump right in. + +When you finish reading this article, you should be able to: + +- list all possible arguments that can be used with the `Array#splice` method + +## Notation + +For clarity in this article and moving forward in the course, we'll be notating +methods with `#` to clarify how they should be called. For example, +`Array#splice` refers to the method that should be called on an array, +`arr.splice()` where `arr` is some array variable. Likewise `String#toUpperCase` +refers to the method that should be called on a string, `str.toUpperCase()` +where `str` is some string variable. We'll opt to refer to methods using this +notation because some methods can be called on multiple data types, such as +`Array#slice` and `String#slice`. + +## What can Array#splice do? + +Before we explore the nitty-gritty details of the `Array#splice` method, the +first thing to be aware of is that the method will **mutate** the array that it +is called on. That is, `Array#splice` will modify the existing array and _not_ +return a new array. + +### Using splice to remove + +The usage of the `Array#splice` method is easy to mix up because it can be used +to remove or insert elements into an array. That's right - it can perform +"opposite" operations, even at the same time! For now, we'll begin by _only_ +removing elements from an array: + +```javascript +let colors = ["red", "yellow", "blue", "green", "orange", "brown", "gray"]; +let returnVal = colors.splice(2, 3); +console.log(colors); // [ 'red', 'yellow', 'brown', 'gray' ] +console.log(returnVal); // [ 'blue', 'green', 'orange' ] +``` + +The first two arguments for splice correspond to 1) the target index and 2) how +many elements to remove. The call `colors.splice(2, 3)`, will remove the next +three elements beginning at index 2. This means that the elements at indices 2, +3, and 4 are removed. + +Note that splice returns an array containing the elements that were removed and +also has the effect of removing the elements from the _original_ array, mutating +it in-place. + +### Using splice to insert + +To use the splice method to insert new elements into an array, we can pass in +any number of additional arguments representing the values to insert: + +```javascript +let colors = ["red", "yellow", "blue"]; +let returnVal = colors.splice(1, 0, "RebeccaPurple", "CornflowerBlue"); +console.log(colors); // [ 'red', 'RebeccaPurple', 'CornflowerBlue', 'yellow', 'blue' ] +console.log(returnVal); // [] +``` + +The method call `colors.splice(1, 0, 'RebeccaPurple', 'CornflowerBlue')` +translates to "target index 1, remove the next 0 elements, then insert +`'RebeccaPurple'` and `'CornflowerBlue'`." + +### Using splice like a pro + +Naturally, we can combine these two functionalities! Say we wanted to target +index 2, remove the next 3 elements, then insert `'Gainsboro'`, `'Ivory'`, and +`'Khaki'`: + +```javascript +let colors = ["red", "yellow", "blue", "green", "black", "beige"]; +let removed = colors.splice(2, 3, "Gainsboro", "Ivory", "Khaki"); +console.log(colors); // [ 'red', 'yellow', 'Gainsboro', 'Ivory', 'Khaki', 'beige' ] +console.log(removed); // [ 'blue', 'green', 'black' ] +``` + +Bam. What a versatile method! Always feel free to reference the +[documentation][mdn-splice] for the method when you are struggling to remember +its usage: + +## What you've learned + +- Array#splice has two required arguments + - the target index + - the number of elements to remove beginning at that target index +- Array#splice can also take in any number of values to be inserted at the + target index + +[mdn-splice]: + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice + +________________________________________________________________________________ +# String#split and Array#join + +We've seen previously that strings and arrays share many similar properties. For +example, strings and arrays both have a `length` and can have multiple indices. +Because of this, you may find it useful to "convert" between the two types. + +When you finish this article, you should be able to: + +- use the `String#split` method to turn a string into an array +- use the `Array#join` method to turn an array into a string + +## String#split + +The [String#split][string-split-mdn] method is called on a string and accepts a +"separator" string as an argument. The method will return an array where the +elements are the resulting substrings when we cut at the "separators": + +```javascript +let sentence = "follow the yellow brick road"; +let words = sentence.split(" "); +console.log(words); // [ 'follow', 'the', 'yellow', 'brick', 'road' ] +console.log(sentence); // 'follow the yellow brick road' +``` + +Note that the original string is _not mutated_, rather a new array is returned. +A common pattern is to split a sentence string on a space (' '), but you can +split on any separator as you see fit: + +```javascript +let sentence = "follow the yellow brick road"; +console.log(sentence.split(" ")); // [ 'follow', 'the', 'yellow', 'brick', 'road' ] +console.log(sentence.split("the")); // [ 'follow ', ' yellow brick road' ] +console.log(sentence.split("o")); // [ 'f', 'll', 'w the yell', 'w brick r', 'ad' ] +``` + +A pattern you may find useful is that when you split on a separator string, it +is guaranteed that that separator will not be in the resulting array, +effectively removing it. See the example of `sentence.split('the')` above. This +may come in handy, so keep it in mind! + +## Array#join + +The [Array#join][array-join-mdn] method is called on an array and accepts a +"separator" string as an argument. The method will return a string where +elements of the array are concatenated together with the "separator" between +each element: + +```javascript +let words = ["run", "around", "the", "block"]; +let sentence = words.join(" "); +console.log(sentence); // 'run around the block' +console.log(words); // [ 'run', 'around', 'the', 'block' ] + +console.log(words.join("_")); // 'run_around_the_block' +console.log(words.join("HI")); // 'runHIaroundHItheHIblock' +``` + +`Array#join` does not mutate the original array, instead it will return a new +string. + +## A clever combination + +It's pretty evident that `String#split` and `Array#join` are "opposite" methods. +That is: + +- we use split to turn a string into a array +- we use join to turn an array into a string + +By combining these two methods we can accomplish some cool behavior: + +```javascript +let str = "I don't know what I want to eat"; +let newStr = str.split("I").join("we"); +console.log(newStr); // 'we don't know what we want to eat' +``` + +Whoa! We were able to replace every substring "I" with the substring "we". We +know that the line `str.split('I').join('we')` evaluates from left to right. +This means that the `split` will cut the string wherever there is an 'I', +leaving a gap where the 'I's were. Then, the `join` will fill those gaps with +'we's. + +## What you've learned + +- we can use `String#split` and `Array#join` to convert between strings and + arrays +- both methods do not mutate their input + +[string-split-mdn]: + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split +[array-join-mdn]: + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join + +________________________________________________________________________________ +# WEEK-01 DAY-5
*Control Flow* {ignore=true} +________________________________________________________________________________ +# Determining Types + +Sometimes you want to know the type of value store in a variable so that you can +safely do things with it. If your function expects an array in its parameter but +gets a number, you can't call the `map` method on that! + +In this article you will learn how to figure out if a value in a variable is + +* A string +* A number +* A function +* An array + +## The typeof operator + +Not all operators in JavaScript require two arguments like the `+` operator for +addition, the `=` for assignment, and the `%` operator for modulo division. +Those are all called _binary_ operators because they take two (bi-) operands, +or things that are operated on. + +JavaScript kindly gives you the operator `typeof` which acts on a single value. +Operators that take only one operand are called _unary_ operators because "u +only give them one value!" (That's a joke. "uni-" or "una-" is one.) + +Here are some examples of what you'd expect to see with the `typeof` operator. + +```js +let s = 'This is a string'; +console.log(typeof s); // 'string' + +let n = 6.28; +console.log(typeof n); // 'number' + +let sum = function (a, b) { + return a + b; +} +console.log(typeof sum); // 'function' +``` + +Note that the value returned from the `typeof` operator is a String data type. +So, if you want to check if a value is a number, you could do this. + +```js +if (typeof n === 'number') { + // It is a number. Do some maths! +} else { + console.log('I really wanted a number. :-('); +} +``` + +## How to tell if a value is an array + +Unfortunately, due to a _really old bug_ in the way that JavaScript works, a bug +that no one can fix because people wrote code that relies on the bug for +decades, you cannot use the `typeof` operator to figure out if something is an +array. + +```js +let a = [1, 2, 3]; +console.log(typeof a); // 'object' +``` + +Gee, JavaScript. That's not helpful. Thanks. + +Luckily, it only took 12 years for JavaScript to include a way to test if a +value is an array. To do so, you use the `Array.isArray` method like this. + +```js +let a = [1, 2, 3]; +Array.isArray(a); // true + +let n = 6.28; +Array.isArray(n); // false + +let f = function () {} +Array.isArray(f); // false +``` + +## Practical use in "real" code + +Oddly enough, you won't see a lot of code in real-world applications testing if +a value is one type or another. A lot of JavaScript functions just _assume_ that +they will get arguments of the right kind because the parameter names imply what +kind of value to pass in. For example, the following function has a parameter +named `sentence`. + +```js +function reverseTheSentence(sentence) { + // ... code here ... +} +``` + +Most developers will know that the function probably wants `sentence` to be a +string value. They just won't pass in an array or number or ... well, anything +other than a string. Because that's just not polite. They'd expect any other +kind of value to cause the `reverseTheSentence` to malfunction. Only when you +know that people that don't respect your code will use it should you add in some +kind of check like this. + +```js +function reverseTheSentence(sentence) { + if (typeof sentence !== 'string') { + // Tell the developer they are using + // the function wrong. + } + // ... code here ... +} +``` + +## What you've seen + +This article has shown you two ways to determine if a value is a kind of type: + +* the `typeof` operator to use to test if a value is a number, a string, or + a function; and, +* the `Array.isArray` method to check if a value is an array. + +Use them as much (or as little) as you need! + +________________________________________________________________________________ +# The Null Type (And Undefined) + +You've met numbers and string, Booleans and arrays. There's another type often +used in JavaScript: the Null type. And, it's a special type. + +In this article, you will learn about the Null type, its value, and how to work +with it in JavaScript. + +## A type with only one value + +You have seen that the String type can have an "infinite" number of values +(within the limits of your computer memory). For example, the String type +represents _any_ of the following values. + +```js +// Examples of values with the String type +'hello, world' +"this is a string" +`Where is my pudding?` +'' +'A really long string.........................................................' +``` + +The Number type also has this aspect. Any number that you can reasonable express +in JavaScript has the Number type. + +```js +// Examples of values with the Number type +-100 +99 +6.28 +Infinity +``` + +You also know about the Boolean type. It can have only two values. + +```js +// The only two values of Boolean type +true +false +``` + +There are not _more_ Boolean values. You can't dream up more. There are only +two, those two. + +The Null type has one and exactly one value. + +```js +// The only value that has the Null type +null +``` + +It's just that word: `null`. No quotation marks. No other fancy things. Just +`null`. + +## The meaning of null + +This is a harder subject to tackle because it's a _philosophical_ subject. Many +people ask, "What does the value of `null` mean in a program?" There are a +couple of answers that programmers give to this. None of them are wrong. None of +them are right. They just are. In the presence of `null`, the code you write +determines which of the following meanings `null` has. + +* The value `null` means _the absence of a value_ or _no value_ +* The value `null` means _an unknown value_ +* The value `null` is a nuisance and I hate it and wish it were never invented + +During your software programming career, you will likely have all three of those +opinions, sometimes at the same time. Let's take a look at some examples to try +to figure this out. + +## The absence of a value + +Let's say you wrote a function that splits a string into words, reverses them, +and puts them back together in reverse order. You can do that with the methods + +* `String#split` [link][split]; +* `Array#reverse` [link][reverse]; and, +* `Array#join` [link][join]. + +That function could look like this. + +```js +function reverseTheSentence(sentence) { + let parts = sentence.split(' '); + parts.reverse(); + return parts.join(' '); +} +``` + +That's great! It works! But, what happens if someone doesn't care about what +your function and just decides to pass in something that's not a string? It +would make sense that reversing something that is not a string should lead to no +value, the absence of a value, because the input to the function doesn't make +sense. In that case, you can just return a `null` because there is _no value_ +that the function can return that would make sense. + +```js +function reverseTheSentence(sentence) { + if (typeof sentence !== 'string') { + return null; + } + let parts = sentence.split(' '); + parts.reverse(); + return parts.join(' '); +} +``` + +## An unknown value + +There are a lot of programmers that will argue that `null` cannot be an unknown +value. "The value is known!" they'll exclaim. "The value is 'null'! It's known! +It's 'null'! Stop saying it's not known!" + +There are programmers that vehemently disagree with that. + +![shrug](images/woman-shrugging_1f937-200d-2640-fe0f.png) + +## Checking if a value is null + +If you had hoped that you could use the `typeof` operator to check if a value is +`null`, then you're out of luck. + +```js +// Useless code. +console.log(typeof null); // 'object' +``` + +Silly JavaScript. Instead of using the `typeof` operator, you can just _compare_ +the value to `null` because there is only one value of the Null data type and +it's always `null`. Take a look at the following code and figure out what you +think it will produce. + +```js +let a = []; +let x = null; + +if (a === null) { + console.log('a is null'); +} else if (x === null) { + console.log('x is null'); +} +``` + +## Oh, and there's that undefined value, too + +Just like the `null` value that is the only value of the Null data type, there +is `undefined` which is the only value of the Undefined data type. + +If you're asking yourself, "Wait, if 'null' is no value or the absence of a +value, then what the heck does 'undefined' mean?", well you're not the only one. + +Have a look at this code. + +```js +let value; + +value = 6.28; +console.log(value); +``` + +You probably will not be surprised to see that it will print out "6.28" because +that's the value of `value`. But, what if you did this? What does that new +`console.log` print? + +```js +let value; +console.log(value); // <- what does this print? + +value = 6.28; +console.log(value); +``` + +If you guessed that it prints "undefined", you're right! When you declare a +variable, it's very first value is `undefined`. Most of the time, though, you'll +just immediately set it to a value. + +```js +let value = 6.28; +``` + +So, an uninitialized variable has the value `undefined` which is the only value +of the Undefined data type. To test for it, you can use the `typeof` operator +_or_ the strict equality operator. Using the strict equality operator is the +more common way to do that, now. + +```js +// Test if a value is undefined +if (value === undefined) { + // do a thing +} + +// You can also do it this way, but +// it is considered passé. +if (typeof value === 'undefined') { + // do a thing +} +``` + +## What happens when... + +Interestingly enough, all functions actually _do_ return values. Have a look at +this function. What value does it return? (Not a trick question.) + +```js +function returnsTrue() { + return true; +} +``` + +Yes, it returns the value `true`. But, what about this function? + +```js +function returnsWhat() { + return; +} +``` + +There's a `return` statement there but it does not specify a value. If there is +not value specified, what do you think this function returns? Try putting the +function definition above and the code below into a code runner and seeing what +happens. + +```js +console.log(returnsWhat()); +``` + +One you figure that out, try the same experiment but with this function. What +do you think it returns. It doesn't even have a `return` statement in it! + +```js +function whatIsThis() { +} +``` + +## What you've learned + +There is a special value in JavaScript represented as `null` which means "no +value" or "unknown value". It is the only value of the Null data type. You can +check that a value is `null` by using the strict equality operator `x === null`. + +The value `undefined` is used by JavaScript for variables that have not been +assigned a value. Also, functions that do not return an explicit value return +the value `undefined`. You can test if a value is `undefined` by using the +strict equality operator `x === undefined`. + +[reverse]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse +[split]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/split +[join]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join + +________________________________________________________________________________ +# Catch Me If You Can + +Sometimes bad things happen to good programs. Some person may enter some badly +formatted information. Another computer may try to attack your program by +sending it wonky data. A network could go down. A file can become corrupt. When +this happens, your running software will have some errors. This article is about +how you can recover from those errors with "structured exception handling". + +In this article you'll learn the answers to: + +* What _is_ structured exception handling? +* How can I do that in JavaScript? +* How can I make my own errors? +* What else can I do with it? +* Shouldn't I just always do this? + +## Structured exception handling + +Oddly enough, there are very few error-handling mechanisms in use, today, in all +programming languages. There are really only three ways that programming +language provide structured exception handling. + +* **Error or error code reporting** as found in languages like C and Go +* **Continuable exceptions** as found in Common Lisp +* **Stack unwinding** which is found in almost every modern programming + language including JavaScript and Python + +In the stack-unwinding paradigm, which is the one you'll use in JavaScript, when +an error occurs, the JavaScript interpreter (the thing running your JavaScript +code) looks for some kind of handler for that error. It has a very specific way +of searching for those handlers. The way JavaScript searches for the handlers is +very similar to the way it happens in Python, C++, Java, C#, and a lot of other +languages. Once you learn it, here, you will be able to handle errors when +writing code in all of those languages. + +## Try and catch + +Say you have some code that may have an error. For example: + +```js +function sumArray(array) { + let sum = 0; + for (let i = 0; i < array.length; i += 1) { + sum += array[i]; + } + return sum; +} +``` + +If someone calls the above function with the code `sumArray(null)`, then they +will get the error because the `for` loop is trying to get the `length` property +of the `array` parameter which is `null`. + +``` +TypeError: Cannot read property 'length' of null +``` + +To prevent this from ruining your program, you wrap code that may have an error +in a **try block**. Now, you've seen other blocks already: `if` blocks, `for` +blocks, `function` blocks. Basically, if there are curly braces around some +lines of code, that's a **code block** of some kind. A _try block_ is just some +curly braces with the `try` keyword. + +```js +// THIS IS AN INCOMPLETE BLOCK OF CODE +function sumArray(array) { + let sum = 0; + + // The try block wraps the for loop. If some + // error occurs, the try block will give you + // a chance to react to it so that the program + // doesn't terminate. + try { + for (let i = 0; i < array.length; i += 1) { + sum += array[i]; + } + } // needs something more here + + return sum; +} +``` + +The `try` block tells JavaScript that it needs to watch the code inside the +curly braces for an error. Now, you have to tell JavaScript what to do when +there _is_ an error. You do that in the `catch` block that should immediately +follow the `try` block. The `catch` block accepts a single parameter that +(usually) contains an object that describes the error that occurred. In the +case of the `sumArray` method, if an error occurs, you could return the value +`undefined` rather than letting an error terminate your program. You could also +log the error to the "error" output. + +```js +function sumArray(array) { + let sum = 0; + + try { + for (let i = 0; i < array.length; i += 1) { + sum += array[i]; + } + } catch (e) { + console.log(e); + return null; + } + + return sum; +} + +sumArray(null); +``` + +Just to state it, again: the _catch block_ runs when an error occurs in the _try +block_. If no error occurs in the _try block_, the _catch block_ **does not +run**. + +That `(e)` after the word `catch` is a variable that contains any error that was +thrown and caught by this `try-catch` block. It doesn't have to be named `e`. + +```js +function sumArray(array) { + let sum = 0; + + try { + for (let i = 0; i < array.length; i += 1) { + sum += array[i]; + } + } catch (pancakes) { + console.log(pancakes); + return null; + } + + return sum; +} + +sumArray(null); +``` + +Here is the same code but, instead of a variable named "e", there is a variable +named "pancakes". Now, if an error is thrown, the variable "pancakes" will +contain it. By long-standing tradition, the variables used with the catch block +are normally "e", "err", or "error". + +```js +// CODE SNIPPET, WILL NOT RUN +} catch (e) { +``` + +```js +// CODE SNIPPET, WILL NOT RUN +} catch (err) { +``` + +```js +// CODE SNIPPET, WILL NOT RUN +} catch (error) { +``` + +Now, when you run the code `sumArray(null)`, you should see something like the +following, if you run it in the online code editor. + +``` +TypeError: Cannot read property 'length' of null + at sumArray (/tmp/file.js:5:31) + at Object. (/tmp/file.js:16:1) + at Module._compile (internal/modules/cjs/loader.js:1158:30) + at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10) + at Module.load (internal/modules/cjs/loader.js:1002:32) + at Function.Module._load (internal/modules/cjs/loader.js:901:14) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) + at internal/main/run_main_module.js:18:47 +``` + +In that code sample, after the `sumArray(null)` call, the lines that begins +`TypeError` is the error that occurred. The next 10 lines are what is known as a +**stack trace**. You'll end up seeing these a lot, most likely, as you continue +your career in software programming. This is the first line in understanding +errors in your code. The _stack trace_ shows on the first line where the error +occurred: `sumArray (/tmp/file.js:5:31)` means that it occurred in the +`sumArray` method on line 5 of the content, at character 31. If you open up one +of the coding problems, paste that code block in, and run it, you'll see similar +output in the output block. + +The last line `undefined` is the return value of the `sumArray(null)` invocation +that now happens when an error occurs. + +That is how the so-called **try-catch block** works. + +## How can I make my own errors? + +To create your own errors with structured exception handling, you first need to +create an error object with the message that describes the error. Then, you need +to "throw" the error. That code would look like either of these two lines, the +only difference being the `new` keyword. They both work exactly the same. + +```js +throw Error('this happened because I wanted it to'); +throw new Error('this happened because I wanted it to'); +``` + +## What else is there? + +Turns out that you can have one more block on the _try-catch block_. It is the +**finally block**. The _finally block_ runs whether or not an error occurs. It +_always_ runs. + +```js +function sumArray(array) { + let sum = 0; + + try { + for (let i = 0; i < array.length; i += 1) { + sum += array[i]; + } + } catch (e) { + console.log(e); + return null; + } finally { + console.log('you will always see this.'); + } + + return sum; +} ``` -For more details see [GitHub Flavored Markdown](https://guides.github.com/features/mastering-markdown/). +## How do I best use this? + +At this point, you may be asking yourself, "Self, since errors can occur +everywhere, shouldn't I just wrap _all_ of my code in these _try-catch blocks_?" + +No. No, you shouldn't. + +Every **try-catch block** introduces another slow-down in your code. If you're +writing code that you want to run as fast as possible, then you write as few +_try-catch blocks_ as possible. Also, it makes the code pretty cluttered with +all of the indentation and curly braces. When at all possible, you should write +**defensive code** which checks for bad values before errors get thrown in your +code. Rather than using a _try-catch block_ in the `sumArray` function, you +could defend against bad values of the `array` parameter like so. -### Jekyll Themes +```js +function sumArray(array) { + if (array === null) { + return null; + } -Your Pages site will use the layout and styles from the Jekyll theme you have selected in your [repository settings](https://github.com/bgoonz/lambda-prep/settings). The name of this theme is saved in the Jekyll `_config.yml` configuration file. + let sum = 0; + for (let i = 0; i < array.length; i += 1) { + sum += array[i]; + } + return sum; +} +``` + +## Review -### Support or Contact +The _try-catch-finally block_ is a mechanism to handle errors in your code. You +should _not_ wrap all of your code in these blocks because it can seriously +degrade the performance of your application. Instead, only wrap those portions +of the code that you want to guard against throwing exceptions. -Having trouble with Pages? Check out our [documentation](https://docs.github.com/categories/github-pages-basics/) or [contact support](https://support.github.com/contact) and we’ll help you sort it out. +A better choice, in JavaScript and all programming languages, is to be +defensive about your programming and choose to check that the value that you +have has the functionality that you desire by adding code like + +```js +if (value !== undefined) {} +if (value !== null) {} +``` From 520249afbd583a1767627318c09e8b9f6f8125ba Mon Sep 17 00:00:00 2001 From: Bryan C Guner <66654881+bgoonz@users.noreply.github.com> Date: Sat, 3 Apr 2021 19:16:15 -0400 Subject: [PATCH 4/4] Create README.md --- README.md | 3455 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 3455 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..756e3e8 --- /dev/null +++ b/README.md @@ -0,0 +1,3455 @@ +# Prep-Work + +## [deployment](https://60637489113cfe1345c7fcf9--jolly-shannon-bbcd09.netlify.app/) + + +0.\) Links: + +| Name | Hyperlink | +| :-------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| OKTA | [https://lambdaschoolsso.okta.com/login/login.htm?fromURI=%2Fapp%2FUserHome](https://lambdaschoolsso.okta.com/login/login.htm?fromURI=%2Fapp%2FUserHome) | +| Calendar | [https://calendar.google.com/calendar/u/0/embed?src=c\_2q0kvam9h9k5i6t40qp5n18dh8@group.calendar.google.com](https://calendar.google.com/calendar/u/0/embed?src=c_2q0kvam9h9k5i6t40qp5n18dh8@group.calendar.google.com) | +| Slack | [https://app.slack.com/client/T4JUEB3ME/G01QG65CN75](https://app.slack.com/client/T4JUEB3ME/G01QG65CN75) | +| | | +| | | +| | | +| | | +| | | +| Prep Work | [https://apply.lambdaschool.com/courses/web/](https://apply.lambdaschool.com/courses/web/) | + + + + + +1.\) Platforms we need while attending class: + + + +2.\) Web Development Software: + + + +3.\) Pre-Course Work + + +``` +. +├── README.html +├── README.md +├── SUMMARY.html +├── SUMMARY.md +├── codeswing.json +├── comparison.png +├── demo.html +├── directory.html +├── index.html +├── javascript-practice +│ ├── 00_expressions_variables +│ │ ├── exercises +│ │ │ ├── A_executing_code_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── B_expressions_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── C_variables_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── D_string_indexing_and_methods_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ +│ │ ├── +│ │ └── solutions +│ │ ├── A_executing_code_solution +│ │ │ ├── age.js +│ │ │ ├── greeting.js +│ │ │ ├── +│ │ │ ├── thirsty.js +│ │ │ └── whoami.js +│ │ ├── B_expressions_solution +│ │ │ ├── boolean-expressions.js +│ │ │ ├── comparisons.js +│ │ │ ├── number-expressions.js +│ │ │ ├── +│ │ │ └── string-expressions.js +│ │ ├── C_variables_solution +│ │ │ ├── four.js +│ │ │ ├── one.js +│ │ │ ├── +│ │ │ ├── three.js +│ │ │ ├── two.js +│ │ │ └── zero.js +│ │ ├── D_string_indexing_and_methods_solution +│ │ │ ├── a-tedious-task.js +│ │ │ ├── dare-to-decipher.js +│ │ │ ├── proper-patterns.js +│ │ │ ├── +│ │ │ └── small-string-snippets.js +│ │ +│ ├── 01_conditionals +│ │ ├── exercises +│ │ │ ├── A_conditionals_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ +│ │ ├── +│ │ └── solutions +│ │ ├── A_conditionals_solution +│ │ │ ├── one.js +│ │ │ ├── +│ │ │ ├── three.js +│ │ │ ├── two.js +│ │ │ └── zero.js +│ │ +│ ├── 02_functions +│ │ ├── exercises +│ │ │ ├── A_functions_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── B_functions_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── C_functions_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ +│ │ ├── +│ │ └── solutions +│ │ ├── A_functions_solution +│ │ │ ├── average.js +│ │ │ ├── ends-with-t.js +│ │ │ ├── half.js +│ │ │ ├── is-div-by-4.js +│ │ │ ├── is-long.js +│ │ │ ├── keep-it-quiet.js +│ │ │ ├── +│ │ │ ├── snippet-0-1.js +│ │ │ ├── snippet-0-2.js +│ │ │ ├── snippet-0-3.js +│ │ │ └── snippet-0-4.js +│ │ ├── B_functions_solution +│ │ │ ├── ends-in-ly.js +│ │ │ ├── funny-sound.js +│ │ │ ├── longer.js +│ │ │ ├── one-or-none.js +│ │ │ ├── parity.js +│ │ │ ├── +│ │ │ ├── starts-with-r.js +│ │ │ ├── string-size.js +│ │ │ └── wacky-word.js +│ │ ├── C_functions_solution +│ │ │ ├── average-of-four.js +│ │ │ ├── case-changer.js +│ │ │ ├── contains.js +│ │ │ ├── divisible.js +│ │ │ ├── in-range.js +│ │ │ ├── larger.js +│ │ │ ├── number-change.js +│ │ │ +│ │ +│ ├── 03_loops +│ │ ├── exercises +│ │ │ ├── A_loops_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── B_loops_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── C_loops_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ +│ │ ├── +│ │ └── solutions +│ │ ├── A_loops_solution +│ │ │ ├── count-up.js +│ │ │ ├── evens.js +│ │ │ ├── min-to-max.js +│ │ │ ├── one-to-four.js +│ │ │ ├── +│ │ │ ├── snippet-1.js +│ │ │ ├── snippet-2.js +│ │ │ ├── snippet-3.js +│ │ │ ├── snippet-4.js +│ │ │ ├── snippet-5.js +│ │ │ └── string-iterate.js +│ │ ├── B_loops_solution +│ │ │ ├── div-by-either.js +│ │ │ ├── five-multiples-of.js +│ │ │ ├── no-ohs.js +│ │ │ ├── odd-sum.js +│ │ │ ├── product-up-to.js +│ │ │ ├── +│ │ │ ├── string-repeater.js +│ │ │ └── sum-up-to.js +│ │ ├── C_loops_solution +│ │ │ ├── censor-e.js +│ │ │ ├── divisible-range.js +│ │ │ ├── fizz-buzz.js +│ │ │ ├── raise-power.js +│ │ │ ├── remove-capitals.js +│ │ │ ├── reverse-iterate.js +│ │ │ +│ │ +│ ├── 04_arrays +│ │ ├── exercises +│ │ │ ├── A_arrays_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── B_arrays_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── C_arrays_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ +│ │ ├── +│ │ └── solutions +│ │ ├── A_arrays_solution +│ │ │ ├── bleep-vowels.js +│ │ │ ├── divisors.js +│ │ │ ├── filter-long-words.js +│ │ │ ├── num-odds.js +│ │ │ ├── +│ │ │ ├── stay-positive.js +│ │ │ ├── strings-to-lengths.js +│ │ │ └── total.js +│ │ ├── B_arrays_solution +│ │ │ ├── choose-divisibles.js +│ │ │ ├── make-acronym.js +│ │ │ ├── maximum.js +│ │ │ ├── reverse-array.js +│ │ │ ├── +│ │ │ ├── word-count.js +│ │ │ └── your-average-function.js +│ │ ├── C_arrays_solution +│ │ │ ├── alternating-caps.js +│ │ │ ├── common-elements.js +│ │ │ ├── lengthiest-word.js +│ │ │ ├── number-range.js +│ │ │ ├── remove-short-words.js +│ │ │ +│ │ +│ ├── 05_nesting +│ │ ├── exercises +│ │ │ ├── A_nested_loops_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── B_two_dimensional_arrays_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ ├── C_more_problems_exercise +│ │ │ │ ├── README.html +│ │ │ │ ├── README.md +│ │ │ │ +│ │ │ +│ │ ├── +│ │ └── solutions +│ │ ├── A_nested_loops_solution +│ │ │ ├── pair-print.js +│ │ │ ├── print-combinations.js +│ │ │ ├── +│ │ │ ├── snippet-1.js +│ │ │ ├── snippet-2.js +│ │ │ ├── snippet-3.js +│ │ │ ├── snippet-4.js +│ │ │ ├── snippet-5.js +│ │ │ └── two-sum.js +│ │ ├── B_two_dimensional_arrays_solution +│ │ │ ├── make-matrix.js +│ │ │ ├── print-2d.js +│ │ │ ├── +│ │ │ ├── total-product.js +│ │ │ ├── two-sum-pairs.js +│ │ │ └── zipper.js +│ │ ├── C_more_problems_solution +│ │ │ ├── remove-dupes.js +│ │ │ ├── remove-first-vowel.js +│ │ │ ├── remove-vowels.js +│ │ │ ├── +│ │ │ ├── shorten-long-words.js +│ │ │ └── spam.js +│ │ +│ ├── 06_decomposition_pattern +│ │ ├── A_decomposing_problems_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ ├── B_decomposing_problems_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ ├── C_decomposing_problems_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ +│ ├── 07_objects +│ │ ├── A_objects_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ ├── B_objects_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ ├── C_objects_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ +│ ├── 08_higher_order_functions +│ │ ├── A_native_callback_methods_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ ├── B_native_callback_methods_exercise +│ │ │ ├── README.html +│ │ │ ├── README.md +│ │ │ +│ │ +│ +├── js.js +├── one-of-every-tag.html +├── readme +│ ├── README.html +│ ├── README_files +│ │ ├── katex.min.css +│ │ +│ +├── resources.html +├── resources.md +├── script.js +├── style.css +└── tree.md + +66 directories, 241 files + + + + + +``` +# WEEK 1
*Introduction to JavaScript (Part 1)* {ignore=true} +________________________________________________________________________________ + + + +[**Expression Learning Objectives**](#expression-learning-objectives) +[**Intro to Functions Learning Objectives**](#intro-to-functions-learning-objectives) +- [Hello World](#hello-world) + - [Getting visual feedback in your programs](#getting-visual-feedback-in-your-programs) + - [Code comments](#code-comments) +- [The Number Type](#the-number-type) + - [All the numbers](#all-the-numbers) + - [The basic arithmetic operators](#the-basic-arithmetic-operators) +- [The String Type](#the-string-type) + - [Writing a valid string](#writing-a-valid-string) + - [Calculating length](#calculating-length) + - [Indexing a string](#indexing-a-string) + - [Concatenation](#concatenation) +- [The Boolean Type](#the-boolean-type) + - [Logical Operators](#logical-operators) + - [De Morgan's Law](#de-morgans-law) +- [Comparison Operators](#comparison-operators) + - [The relative comparators](#the-relative-comparators) + - [=== vs ==](#vs) +- [Basic Variables](#basic-variables) + - [Initializing a variable](#initializing-a-variable) + - [Manipulating variables](#manipulating-variables) + - [NaN](#nan) +- [Introduction to Functions](#introduction-to-functions) + - [Writing Functions](#writing-functions) + - [Invoking or "calling" a function](#invoking-or-calling-a-function) + - [Returning a value](#returning-a-value) + - [The importance of naming](#the-importance-of-naming) +- [Parameters and Arguments](#parameters-and-arguments) + - [The difference between Parameters and Arguments](#the-difference-between-parameters-and-arguments) + +[**Control Flow and Array Learning Objectives**](#control-flow-and-array-learning-objectives) +- [Control Flow - Conditional Statements](#control-flow-conditional-statements) + - [A Quick Word on Syntax](#a-quick-word-on-syntax) + - [Writing Conditional Statements](#writing-conditional-statements) +- [Mutually Exclusive Conditions](#mutually-exclusive-conditions) + - [When to use if statements](#when-to-use-if-statements) +- [Control Flow - Looping](#control-flow-looping) + - [Looping](#looping) + - [Translating From One Loop to Another](#translating-from-one-loop-to-another) +- [The Array Type](#the-array-type) + - [Using arrays](#using-arrays) + - [Indexing arrays](#indexing-arrays) + - [Working with arrays](#working-with-arrays) + - [Concatenation with arrays](#concatenation-with-arrays) + +[**Intermediate Functions Learning Objectives**](#intermediate-functions-learning-objectives) +- [Function Expressions](#function-expressions) + - [Functions as first-class objects](#functions-as-first-class-objects) +- [Two-Dimensional Arrays (2D Arrays)](#two-dimensional-arrays-2d-arrays) + - [Multidimensional Arrays](#multidimensional-arrays) + - [Iterating through 2D Arrays](#iterating-through-2d-arrays) + - [When is a 2D array practical?](#when-is-a-2d-array-practical) +- [Mutability in JavaScript](#mutability-in-javascript) + - [What is mutability?](#what-is-mutability) + - [Mutable or immutable, that is the question](#mutable-or-immutable-that-is-the-question) + - [The mutability misconception](#the-mutability-misconception) +- [Array Splice](#array-splice) + - [Notation](#notation) + - [What can Array#splice do?](#what-can-arraysplice-do) +- [String#split and Array#join](#stringsplit-and-arrayjoin) + - [String#split](#stringsplit) + - [Array#join](#arrayjoin) + - [A clever combination](#a-clever-combination) +- [Determining Types](#determining-types) + - [The typeof operator](#the-typeof-operator) + - [How to tell if a value is an array](#how-to-tell-if-a-value-is-an-array) + - [Practical use in "real" code](#practical-use-in-real-code) +- [The Null Type (And Undefined)](#the-null-type-and-undefined) + - [A type with only one value](#a-type-with-only-one-value) + - [The meaning of null](#the-meaning-of-null) + - [The absence of a value](#the-absence-of-a-value) + - [An unknown value](#an-unknown-value) + - [Checking if a value is null](#checking-if-a-value-is-null) + - [Oh, and there's that undefined value, too](#oh-and-theres-that-undefined-value-too) + - [What happens when...](#what-happens-when) +- [Catch Me If You Can](#catch-me-if-you-can) + - [Structured exception handling](#structured-exception-handling) + - [Try and catch](#try-and-catch) + - [How can I make my own errors?](#how-can-i-make-my-own-errors) + - [What else is there?](#what-else-is-there) + - [How do I best use this?](#how-do-i-best-use-this) + + +________________________________________________________________________________ +# WEEK-01 DAY-1
*Function Introduction* {ignore=true} +________________________________________________________________________________ +# Expression Learning Objectives + +Below is a complete list of the terminal learning objectives for this lesson. +When you complete this lesson, you should be able to perform each of the +following objectives. These objectives capture how you may be evaluated on the +assessment for this lesson. + +1. Given a working REPL interface, write and execute a statement that will print + "hello world" using console.log +2. Identify that strings are a list of characters defined by using double or + single quotes +3. Given an arithmetic expression using +, -, \*, /, %, compute its value +4. Given an expression, predict if its value is NaN +5. Construct the truth tables for &&, ||, ! +6. Given an expression consisting of >, >=, ===, <, <=, compute it's value +7. Apply De Morgan's law to a boolean expression +8. Given an expression that utilizes operator precedence, compute its value +9. Given an expression, use the grouping operator to change it's evaluation +10. Given expressions using == and ===, compute their values +11. Given a code snippet using postfix ++, postfix --, +=, -=, /=, \*=, predict + the value of labeled lines +12. Create and assign a variable using `let` to a string, integer, and a + boolean. Read its value and print to the console.l learning objectives for this lesson. +When you complete this lesson, you should be able to perform each of the +following objectives. These objectives capture how you may be evaluated on the +assessment for this lesson. + +1. Given a working REPL interface, write and execute a statement that will print + "hello world" using console.log +2. Identify that strings are a list of characters defined by using double or + single quotes +3. Given an arithmetic expression using +, -, \*, /, %, compute its value +4. Given an expression, predict if its value is NaN +5. Construct the truth tables for &&, ||, ! +6. Given an expression consisting of >, >=, ===, <, <=, compute it's value +7. Apply De Morgan's law to a boolean expression +8. Given an expression that utilizes operator precedence, compute its value +9. Given an expression, use the grouping operator to change it's evaluation +10. Given expressions using == and ===, compute their values +11. Given a code snippet using postfix ++, postfix --, +=, -=, /=, \*=, predict + the value of labeled lines +12. Create and assign a variable using `let` to a string, integer, and a + boolean. Read its value and print to the console. + +________________________________________________________________________________ +# Intro to Functions Learning Objectives + +Below is a complete list of the terminal learning objectives for this lesson. +When you complete this lesson, you should be able to perform each of the +following objectives. These objectives capture how you may be evaluated on the +assessment for this lesson. + +1. Define a function using function declaration +2. Define a function that calculates the average of two numbers, call it, + pass in arguments, and print it's return value +3. Identify the difference between parameters vs argument terminal learning objectives for this lesson. +When you complete this lesson, you should be able to perform each of the +following objectives. These objectives capture how you may be evaluated on the +assessment for this lesson. + +1. Define a function using function declaration +2. Define a function that calculates the average of two numbers, call it, + pass in arguments, and print it's return value +3. Identify the difference between parameters vs arguments +________________________________________________________________________________ +# Hello World + +Hey Programmer! Welcome to the JavaScript module. In the next few sections, +we'll be learning the fundamentals of the JavaScript programming language. If +it's your first time programming, don't worry; we designed this course +especially for you. We'll have you executing your first lines of code in no +time! + +When you finish this article, you should be able to: + +- use the `console.log` command to print out messages +- use double slashes (`//`) to write code comments + +## Getting visual feedback in your programs + +The first command we'll learn in JavaScript is `console.log`. This command is +used to _print_ something onto the screen. As we write our first lines of code, +we'll be using `console.log` frequently as a way to visually see the output of +our programs. Let's write our first program: + +```javascript +console.log("hello world"); +console.log("how are you?"); +``` + +Executing the program above would print out the following: + +```plaintext +hello world +how are you? +``` + +Nothing too ground breaking here, but pay close attention to the exact way we +wrote the program. In particular, notice how we lay out the periods, +parentheses, and quotation marks. We'll also terminate lines with semicolons +(;). + +> Depending on how you structure your code, sometimes you'll be able to omit +> semicolons at the end of lines. For now, you'll want to include them +> just as we do. + +### Syntax + +We refer to the exact arrangement of the symbols, characters, and keywords as +**syntax**. These details matter - your computer will only be able to +"understand" proper JavaScript syntax. A programming language is similar to a +spoken language. A spoken language like English has grammar rules that we should +follow in order to be understood by fellow speakers. In the same way, a +programming language like JavaScript has syntax rules that we ought to follow! + +As you write your first lines of code in this new language, you may make many +syntax errors. Don't get frustrated! This is normal - all new programmers go +through this phase. Every time we recognize an error in our code, we have an +opportunity to reinforce your understanding of correct syntax. Adopt a growth +mindset and learn from your mistakes. + +Additionally, one of the best things about programming is that we can get such +immediate feedback from our creations. There is no penalty for making a mistake +when programming. Write some code, run the code, read the errors, fix the +errors, rinse and repeat! + +## Code comments + +Occasionally we'll want to leave **comments** or notes in our code. Commented +lines will be ignored by our computer. This means that we can use comments to +write plain english or temporarily avoid execution of some JavaScript lines. The +proper _syntax_ for writing a comment is to begin the line with double forward +slashes (`//`): + +```javascript +// let's write another program!!! +console.log("hello world"); + +// console.log("how are you?"); + +console.log("goodbye moon"); +``` + +The program above would only print: + +```plaintext +hello world +goodbye moon +``` + +Comments are useful when annotating pieces of code to offer an explanation of +how the code works. We'll want to strive to write straightforward code that is +self-explanatory when possible, but we can also use comments to add additional +clarity. The real art of programming is to write code so elegantly that it is +easy to follow. + +"Simplicity is prerequisite for reliability." — Edsger W. Dijkstra + +## What you've learned + +- `console.log` can be used to print to the screen +- using `//` at the front of a line will turn it into a comment; comments are + ignored by JavaScript + +________________________________________________________________________________ +# The Number Type + +The **Number** data type in JavaScript does exactly what you expect! It is used +to represent any numerical values, this includes integers and decimal numbers. +As one of our first data types, we'll be interested in what operations we can +use with numbers. + +When you finish this article, you should be able to: + +- predict the evaluation of arithmetic expressions +- explain the order of operations for JavaScript's arithmetic operators +- use the grouping operator, `()`, to manipulate the order of operations in an + expression + +## All the numbers + +JavaScript's **Number** encompasses numerical values. All of the following values are of number type: + +```javascript +42; +-5; +3.14159; +7.0; +``` + +## The basic arithmetic operators + +For any given data type, we're interested in what operations we can perform with +that type. We use the word _operator_ to refer to the symbol that performs a +particular _operation_. For example, the `+` operator performs the addition +operation. Here are the common arithmetic operators in JS: + +- `+` (addition) +- `-` (subtraction) +- `*` (multiplication) +- `/` (division) +- `%` (modulo) + +With number values and arithmetic operators in hand, we can evaluate our first +expressions: + +```javascript +console.log(2 + 3); // => 5 +console.log(42 - 42); // => 0 +console.log(-4 * 1.5); // => -6 +console.log(25 / 8); // => 3.125 +``` + +Nothing too groundbreaking about the results above. An expression consists of +values and operators. JavaScript will evaluate an expression into a single +value. + +We can write more complex expressions using multiple operators. However, we'll +want to be aware of the general math order of operations. That is, we perform +multiplication-division operations first and then addition-subtraction +operations. To force a specific order of operation, we can use the grouping +operator, `( )`, around a part of the expression: + +```javascript +console.log(5 * 3 + 2); // => 17 +console.log(2 + 3 * 5); // => 17 +console.log((2 + 3) * 5); // => 25 +``` + +### The modulo operation + +All of the math operators listed above are the simple operations you use +everyday, except for maybe modulo `%`. **Modulo gives us the remainder that +results from a division.** For example, `10 % 3` is 1 because when we divide 10 +by 3, we are left with a remainder of 1. We can read `10 % 3` as "ten modulo +three" or "ten mod three." + +```javascript +console.log(10 % 3); // => 1 +console.log(14 % 5); // => 4 +console.log(20 % 17); // => 3 +console.log(18 % 6); // => 0 +console.log(7 % 9); // => 7 +``` + +Modulo is a very useful operation in the realm of computers. We can use it to +check the divisibility of numbers, whether numbers are even, whether they are +prime, and much, much more. Don't take this seemingly simple operation from +granted! We'll provide a ton of practice using these modulo patterns as we move through the course. + +In the order of operations, modulo has the the same precedence as +multiplication-division. So our complete order of math operations in JS is +parentheses, multiplication-division-modulo, addition-subtraction. + +```javascript +// modulo has precedence over addition +console.log(4 + 12 % 5); // => 6 +console.log((4 + 12) % 5); // => 1 +``` + +## What you've learned + +- The **Number** type is used to represent integer and decimal values +- The operators `+`, `-`, `/`, `*` perform the normal math operations of + addition, subtraction, division, multiplication respectively +- `a % b` returns the remainder when we divide `a` by `b`; we call this + operation modulo +- JavaScript follows the usual mathematical order of operations and we can use + the `()` to force precedence + +________________________________________________________________________________ +# The String Type + +This article is about one of JavaScript's primitive data types, **String**. +Strings are what we'll use to represent textual data. This means that strings +are useful in representing things like messages, names, poems, and so on. A +string is a sequence of characters. + +When you finish this article, you should be able to: + +- Write strings using correct syntax +- Use `.length` to obtain a count of the numbers of characters that comprise a + string +- Index a string to refer to a single character +- Concatenate strings together + +## Writing a valid string + +Strings are always wrapped by a pair of single quotation marks (`'`) or by a +pair of double quotation marks (`"`). Between the enclosing quotation marks, we +can put any characters! Here are a six examples of strings: + +```javascript +"potato"; +"New York"; +"azablan@.io"; +"Follow the yellow brick road, please!"; +"365 days a year"; +""; +``` + +Above, notice that we are free to mix in **any** characters into a string. This +includes spaces, numerics, punctuation, and other symbols. The sixth string +above is the empty string; it contains zero characters! + +You are probably wondering why we are allowed to use either single or double +quotes when denoting a string - why is this useful? Maybe we want a string that +_contains_ quotation marks: + +```javascript +// valid strings +'Shakespeare wrote, "To be or not to be"'; +"That's a great string"; +``` + +```javascript +// invalid string +'That's a bad string' +``` + +If we want to use a single quote as a character of a string, we simply need to +enclose the string in double quotes, and vice versa. + +## Calculating length + +Since a single string can contain any number of characters, we may find it +useful to count the number of characters in a string using `.length`: + +```javascript +console.log("ramen".length); // => 5 +console.log("go home!".length); // => 8 +console.log("".length); // => 0 +``` + +## Indexing a string + +Strings consist of multiple characters. These characters are numbered by +**indices** starting at 0. So in the string `'bootcamp'`, `'b'` is at index 0, +`'o'` is at index 1, `'o'` is at index 2, `'t'` is at index 3, and so on. We can +look at particular characters of a string by using `[]` and specifying an index: + +```javascript +console.log("bootcamp"[0]); // => 'b' +console.log("bootcamp"[1]); // => 'o' +console.log("bootcamp"[2]); // => 'o' +console.log("bootcamp"[3]); // => 't' +console.log("bootcamp"[7]); // => 'p' +console.log("bootcamp"[10]); // => undefined +console.log("bootcamp"[-3]); // => undefined +``` + +In general, when we index a string using the expression `string[i]`, we get back +the **single character** at position `i`. Looking at the last two examples +above, if we use an invalid index with a string, the value returned is +`undefined`. This makes since because there is no character at the given +position! It's also worth mentioning that an index should always be a number. + +### The classic "off by one" error + +Bear in mind that indices begin at 0 and not 1! Forgetting this nuance can lead +to incorrect code for both new and experienced programmers alike. Let's hone in +on an important distinction: the index of the last character of a string is +always one less than it's length. + +```javascript +console.log("cat".length); // => 3 +console.log("cat"[3]); // => undefined +console.log("cat"[2]); // => 't' +``` + +In other words, although the `length` of `'cat'` is 3, the index of the last +character (`'t'`) is 2. + +### Using indexOf + +We can also calculate the index of a given character within a string by using +`indexOf`: + +```javascript +console.log("bagel".indexOf("b")); // => 0 +console.log("bagel".indexOf("a")); // => 1 +console.log("bagel".indexOf("l")); // => 4 +console.log("bagel".indexOf("z")); // => -1 +``` + +If we attempt to search for a character that is **not** present in a string, +`indexOf` will return -1. This makes sense because we know that -1 is not a +valid string index. The smallest index possible is 0! + +If we search for a character that appears more than once in a string, +`indexOf` will return the index of the first occurance of that character. + +We can also use `indexOf` to search for a substring of characters. Under this +circumstance, `indexOf` will return the index where the substring begins in the +main string: + +```javascript +console.log("door hinge".indexOf("oor")); // => 1 +console.log("door hinge".indexOf("hi")); // => 5 +console.log("door hinge".indexOf("hint")); // => -1 +``` + +## Concatenation + +Concatenation is just a fancy word for joining strings together into a single +string. To concatenate strings, we use the `+` operator: + +```javascript +console.log("hello" + "world"); // => 'helloworld' +console.log("goodbye" + " " + "moon"); // => 'goodbye moon' +``` + +## What you've learned + +- a **String** is a data type that contains multiple characters enclosed in + quotation marks +- `string.length` returns the number of characters in the `string` +- each character of a string is associated with a number index; the first + character of a string is at index 0 +- we can use `string.indexOf(char)` to obtain the index of `char` within + `string`; if `char` is not found, then -1 is returned +- we can use `+` to concatenate multiple strings, combining them into a single + string + +________________________________________________________________________________ +# The Boolean Type + +The **Boolean** data type is perhaps the simplest type since there are only two +possible values, `true` and `false`. However, we'll find booleans very useful +because they will act as components of later concepts. As programmers, we'll use +booleans to describe the validity of statements. In an abstract sense, _"Today +is Monday"_ and _"one plus one equals ten"_ are examples of statements with +boolean values. That is, they are either `true` or `false`. + +When you finish this article, you should be able to: + +- predict the evaluation of expressions that use the boolean operations of `!`, + `||`, and `&&` +- explain DeMorgan's law + +## Logical Operators + +In the long run, we'll be using booleans to establish logic in our code. For +this reason, the _boolean operators_ can also be referred to as the _logical +operators_. There are only three such operators: + +- `!` (not) +- `&&` (and) +- `||` (or) + +### Logical NOT + +The not (`!`) operator will reverse a boolean value: + +```javascript +console.log(!true); // => false +console.log(!false); // => true +console.log(!!false); // => false +``` + +It's worth mentioning that `!` is a unary operator. This means that the not +operation is applied to a single value. This is in contrast to a binary operator +such as multiplication, which is applied between two values. It does not make +sense to `!` two values together. + +### Logical AND + +The and (`&&`) operator will take two boolean values and will only evaluate to +`true` when both input values are `true`. Otherwise, it will return `false`: + +```javascript +console.log(false && false); // => false +console.log(false && true); // => false +console.log(true && false); // => false +console.log(true && true); // => true +``` + +### Logical OR + +The or (`||`) operator will take two boolean values and will only evaluate to +`false` when both input values are `false`. Otherwise, it will return `true`: + +```javascript +console.log(false || false); // => false +console.log(false || true); // => true +console.log(true || false); // => true +console.log(true || true); // => true +``` + +### Logical order of operations + +We can write boolean expressions that consist of multiple logical operations, but we should be aware of the order of operations. JavaScript will evaluate `!` then `&&` then `||`. + +```javascript +console.log(true || true && false); // => true +console.log(false && !(false || true)); // => false +``` + +In general, `A || B && C` is equivalent to `A || (B && C)` where `A`, `B`, `C` are booleans. + +## De Morgan's Law + +A common mistake in boolean logic is to incorrectly distribute `!` across parentheses. Say we had boolean values of `A`, `B`. Here is something to remember: + +* `!(A || B)` is equivalent to `!A && !B` +* `!(A && B)` is equivalent to `!A || !B` + + +In other words, to correctly distribute `!` across parentheses, we must also flip the operation within parentheses. Beware that: + +* `!(A || B)` is not equivalent to `!A || !B` +* `!(A && B)` is not equivalent to `!A && !B` + +We call this property **De Morgan's Law**. Shout out to Augustus De Morgan of Great Britain. + +## What you've learned + +* `!`, `&&`, `||` are the boolean operators that we can use to establish logic in our code +* De Morgan's Law should be used to distribute `!` against parentheses + +These are just the basics of the type. We'll be seeing more booleans in the upcoming section, so stay tuned for that! + +________________________________________________________________________________ +# Comparison Operators + +In our previous introduction to the boolean data type, we described booleans as +way to represent the validity of an expression. We'll continue this conversation +by exploring **comparison** operators. As you learn about these operators, bear +in mind that all comparisons will result in a boolean, `true` or `false`. + +When you finish this article, you should be able to: + +- Predict the result of expressions that utilize the operators `>`, `<`, `>=` + `<=`, `===`, and `!==` +- Explain the difference between the equality operators `==` and `===` + +## The relative comparators + +- `>` (greater than) +- `<` (less than) +- `>=` (greater than or equal to) +- `<=` (less than or equal to) +- `===` (equal to) +- `!==` (not equal to) + +Using these operators is pretty straightforward. Here are a few examples: + +```javascript +console.log(10 > 5); // => true +console.log(10 < 5); // => false +console.log(1 < 7); // => true +console.log(7 <= 7); // => true +console.log(5 === 6); // => false +console.log(5 !== 6); // => true +console.log("a" !== "A"); // => true +console.log(false === false); // => true +``` + +Notice that a comparison expression always evaluate to a boolean value (`true` +or `false`). Comparison operators like `===` are a useful to compare strings, +booleans, etc. not just numbers. + +**Did you know?** `'a' < 'b'` is valid JS code? When you relatively compare +strings using `>` or `<` you will be comparing them lexicographically. +Lexicographically is fancy shmancy talk for "dictionary" order! A "lesser" +string is one that would appear earlier in the dictionary: + +```javascript +console.log("a" < "b"); // => true +console.log("apple" < "abacus"); // => false +console.log("app" < "apple"); // => true +console.log("zoo" > "mississippi"); // => true +``` + +**Gotcha** capitilized letters are considered lexicographically less than +lower case letters. i.e "A" < "z" // => true. + + +## === vs == + +In JavaScript there are two equality operators triple-equals (`===`) and +double-equals (`==`). The operators differ in how they compare across differing +types. Triple-equals performs the _strict equality_, meaning it will only return +`true` if the types are the same. Double-equals performs the _loose equality_, +meaning it can return `true` even if the values are of different type. +Double-equals may _coerce_ a value into another type for the comparison, and +this behavior is hard to predict: + +```javascript +console.log(5 === "5"); // false +console.log(5 == "5"); // true +console.log(0 === false); // false +console.log(0 == false); //true +``` + +Whoa! Surprised by these results? It can be hard to predict how `==` behaves, so +we will avoid using it in this course and as a best practice. Stick to using +`===` because it respects data types. + +## What you've learned + +- `>`, `<`, `>=`,`<=`, `===`, and `!==` can be used to compare values +- we prefer to use `===` to check for equality because it takes the type into + account. + +________________________________________________________________________________ +# Basic Variables + +Variables are used to store information to be referenced and manipulated in a +computer program. They also provide a way of labeling data with a descriptive +name, so our programs can be understood more clearly by programmers. It is +helpful to think of variables as containers that hold information. Their sole +purpose is to label and store data in computer memory. This data can then be +used and even changed throughout the lifetime of your program. + +When you finish this reading, you should be able to: + +- declare variables using the `let` keyword +- assign values to variables using the assignment operator (`=`) +- use the shortcuts `+=`, `-=`, `++`, `--` to reassign variables +- identify `undefined` as the default value for unassigned variables + +## Initializing a variable + +To initialize a variable in JavaScript we'll need two new pieces of syntax: +`let` and `=`. We can give the variable any name that we wish and assign it a +value. Once we initialize a variable, the variable will evaluate to the value +assigned: + +```javascript +let bootcamp = ""; +console.log(bootcamp); // '' + +let birthYear = 2012; +console.log(birthYear); // 2012 +``` + +**Did you know?** JavaScript variables names can contain any alphanumeric +characters, underscore (\_), or dollar sign (\$). However, they _cannot_ begin +with a number. + +Above are examples of how you'll create variables most of the time, so we'll +grow very familiar with the syntax. As a best practice, we should name our +variables in a way that is descriptive and concise. + +The variable initializations above really consist of two steps: _declaration_ +with `let` and _assignment_ with `=`. Let's break these two steps down. + +### Declaring a variable + +In JavaScript, in order to use a variable, we must _declare_ it. Variable +**declaration** is the act of introducing the variable to the environment. + +To declare a variable, use the `let` keyword, followed by a space and then the +name of the variable. + +```javascript +let bootcamp; +console.log(bootcamp); // undefined +``` + +Once a variable is declared, it will contain `undefined` as it's value. +`undefined` is a common default value in JavaScript, we'll see it come up in a +few different places. You can think of `undefined` as showing that the variable +is empty. + +### Assigning a variable + +Once a variable has been declared, we can assign it a value using single-equals +`=` : + +```javascript +let bootcamp; +console.log(bootcamp); // undefined +bootcamp = ""; +console.log(bootcamp); // '' +``` + +## Manipulating variables + +To change the value of a variable, we need to reassign it to a new value with +`=` : + +```javascript +let num = 42; +console.log(num + 8); // => 50 +console.log(num); // => 42 + +num = num + 10; +console.log(num); // => 52 +``` + +In the code above, `num + 8` will evaluate to `50`, but it will not change the `num` +variable to `50`. If we want to change the `num` variable, we must reassign to +it. + +### Assignment Shorthand + +Changing the value of a number variable is something fairly common in the +programming world. Luckily there is some shorthand operators we can use: + +```javascript +let number = 0; +number += 10; // equivalent to number = number + 10 +number -= 2; // equivalent to number = number - 2 +number /= 4; // equivalent to number = number / 4 +number *= 7; // equivalent to number = number * 7 +console.log(number); // 14 +``` + +We also have other shorthand to add or subtract exactly 1 from a variable, the +increment (`++`) and decrement (`--`) operators: + +```javascript +let year = 3004; +year++; +console.log(year); // 3005 +year--; +console.log(year); // 3004 +``` + +## NaN + +Now that we have the ability to perform arithmetic with variables, let's take a +look at a common programming mistake, getting a result of `NaN` (not a number): + +```javascript +let num; +console.log(num + 3); // NaN +``` + +The above code gives `NaN` because the unassigned `num` variable contains +`undefined`; adding `3` to `undefined` results in `NaN`. In general, any +nonsensical arithmetic will result in `NaN`. Math operations involving +`undefined` is perhaps the most common mistake: + +```javascript +console.log(undefined + 3); // NaN +console.log("fish" * 2); // NaN +``` + +## What you've learned + +- variables are declared with `let` and will contain the value `undefined` by + default +- we can use single-equals `=` to assign variables +- changing a variable requires a reassignment, for which there are many + shortcuts for (`+=`, `-=`, etc.) + +________________________________________________________________________________ +# Introduction to Functions + +We hope you are ready - because you are on the brink of one of the most fun +parts of writing JavaScript: writing **functions**. A function is a procedure of +code that will run when called. We only "write" a function once (**function +declaration**), but we can "use" it as many times as we please (**function +calls**). Functions are the fundamental building blocks of JavaScript and +mastering them is a big step on the road to JavaScript mastery. + +When you finish this reading, you should be able to: + +1. Describe what a function in JavaScript is. +2. Demonstrate how to invoke a function. +3. Write a function using function declaration. +4. Use the `return` keyword to return a value from a function. + +## Writing Functions + +A function is a set procedure of code that will run when called. Functions +really start to make sense when put in the perspective of solving problems. So +for example say you want to find the average of two given numbers. Meaning we +want to take two numbers, add them together then divide by 2: + +```js +> (5 + 5) / 2 +5 + +> (15 + 3) / 2 +9 + +> (7 + 2) / 2 +4.5 +``` + +Writing out the same code again and again gets tedious fast. What you can do +instead is write a new _function_. + +### Function Declaration + +A _function definition_ consists of the function keyword, followed by three +things: + +1. The **name** of the function. +2. A list of _parameters_ to the function, enclosed in parentheses, `()`. +3. The code to be run when this function is run, enclosed in curly + brackets,`{ }`. + +So for our above example of averaging two numbers we could write a function that +would do that for us! We would write something like the following: + +```js +// 1. average is the name of the function +// 2. number1 & number2 are the parameters being passed in +function average(number1, number2) { + // 3. this is the code run every time this function is used + return (number1 + number2) / 2; +} +``` + +First thing to notice for the above `average` function is that we didn't use any +_real_ numbers. You always want to write functions to accept as wide a range of +data as possible. Utilizing the incoming _parameters_ to a function is one of +the keys to making functions flexible. + +In the case of the `average` function, we want to use it to calculate the +average of any two numbers. `number1` and `number2` are the _parameters_ for the +`average` function. In other words, the `average` function expects to be given +two numbers, `number1` and `number2`. We'll be talking a lot more about +parameters later - but for now know that when you define a function with +parameters you are declaring those parameters as usable variables within that +function. + +The beauty of a function is that if we define it in a clever way, it will work +on a whole slew of data! For example, we want `average` to work on any two +numbers, whether or not they are whole numbers, decimal, negative, etc. + +## Invoking or "calling" a function + +Now that we've written a function how do we actually use it? Once defined a +function can be invoked or "called" as many times as we please. + +### Order of code + +Let's step away from `average` for a bit to see how a simple function call +works. Say we run JavaScript code that looks like this: + +```js +console.log("First!"); + +console.log("Second!"); +``` + +Running this code will return exactly as we expect. We will see `First!` printed +out, followed by `Second!`. In other words, JavaScript will evaluate your code +left-to-right and top-to-bottom. Very intuitive! It's exactly how you are +reading these notes right now. + +However, when JavaScript sees a function definition, JavaScript will **not** +evaluate the code inside of the definition. It will only "remember" the code so +we can execute it later. The code below only prints `First!` followed by +`Fourth!`: + +```js +console.log("First!"); + +function callMe() { + console.log("Second!"); + console.log("Third!"); +} + +console.log("Fourth"); + +// when run this code is ran it will print out: +// "First!" +// "Fourth" +``` + +To actually get the code within `callMe` to evaluate, we must _call_ it by using +`callMe()`. The code below will now print out in order: + +```js +function callMe() { + console.log("Second!"); + console.log("Third!"); +} + +console.log("First!"); +// we call the function by adding ending parenthesis +callMe(); +console.log("Fourth!"); + +// when run this code is ran it will print out: +// "First!" +// "Second!" +// "Third!" +// "Fourth" +``` + +Let's say JavaScript is running the file above. Here are the steps it would +take, starting from the tippy top of the code: + +1. JS sees a definition for `callMe`. It will remember this definition in case + we call the function later. It will **not** evaluate the code inside the + function yet. +2. JS prints out `First!` +3. JS sees that we are calling `callMe()`. At this point it will look at the + prior `callMe` definition and run the code inside. It is as if we are + "jumping" to inside the function definition. This means it will print + `Second!` followed by `Third!` +4. JS sees there is no more code to be run inside of `callMe`, so it "jumps" + back to where we originally called `callMe()` +5. JS will continue evaluating in order and print `Fourth!` + +### An average example + +So a declared function is "saved for later use", and will be executed later, +when it is called, also known as being **invoked**. So thinking back to our +average function we can declare the function and then _invoke_ it. + +When we specify what data to use for a function call, we refer to that process +**passing arguments to the function**. + +```js +// this is a function definition +function average(number1, number2) { + return (number1 + number2) / 2; +} + +// this is a function call with the arguments being 15 & 3 +> average(15, 3) +9 + +// this is a function call with the arguments being 5 & 5 +> average(10, 5) +7.5 +``` + +When we call the function `average(15, 3)`, we run the code inside the +_definition_ for `average`. That is, we plug in the parameters with real numbers +(`number1` becomes `10` and `number2` becomes 16). Think of `number1` and +`number2` as _variables_ that contain the values we pass in when we called the +function. Then we proceed by running the code inside the function. The parameter +names `number1` and `number2` used through the body of the function and behave +like variables. + +## Returning a value + +Now that we know how functions are declared and invoked let's talk about the +inside of the function. We'll start with a statement: _Every function in +JavaScript returns `undefined` unless otherwise specified._ + +Now what does that mean? We'll start with a simple example: + +```js +function sayNumber(number) { + console.log(number); +} + +> sayNumber(1); // prints 1 +1 +undefined +``` + +So what happened there? Let's do a quick step by step: + +1. We declared the `sayNumber` function +2. `sayNumber` was called handing in the argument of 1 +3. The `number` parameter is printed to the console +4. Then the function ends without encountering a `return` statement. Since + nothing was specifically returned then the function returned the default + value for a function which is `undefined`. + +Now let's change our above example to use the keyword `return` to return a +value: + +```js +function sayNumber(number) { + console.log(number); + return true; +} + +> sayNumber(1); +1 // sayNumber still prints 1 +true // but now sayNumber returns as true +``` + +Let's go back to our previous `average` function and talk about the `return` we +used there: + +```js +function average(number1, number2) { + return (number1 + number2) / 2; +} + +// the function call for average(10, 16) will return 13 +// so the result variable will be set to 13 +let result = average(10, 16); + +// if we want to check what a function returns we can do this: +console.log(result); // prints `13` + +// we could alternatively do this: +console.log(average(10, 16)); +``` + +When we _call_ a function, we jump to the function definition and run the code +inside. When we hit a `return` statement, we immediately **exit** the function, +jump back to where we _called_ the function, and evaluate the function call to +the value it _returned_. + +**Every function call evaluates to it's return value!** In other words, the +expression `average(10, 16)` evaluates to `13` just like how the expression +`1 + 1` evaluates to `2`. + +Another important rule of the return statement is that it stops function +execution immediately. This means that any code after a `return` will not be +executed! + +```js +function average(number1, number2) { + let sum = number1 + number2; + return sum; + // anything under the first return will not be executed + console.log("this will not run") + return false; +} + + // when the first return is encountered the entire function will return a value +> average(2, 7); +9 +``` + +So the three things to remember about return statements is: + +1. Every function call evaluates to it's return value. +2. Every function in JavaScript returns `undefined` unless a `return` is + specified +3. Once a `return` statement is encountered the function will immediately stop + and return the value, ignoring any code below the `return` statement. + +## The importance of naming + +A quick but very important side note about good naming. Take this to heart right +now: **Good names are important**. Do yourself, and every other programmer +reading your code, a favor by always using significant function and variable +names. + +For example, `x` is a very non-descriptive name for a variable or function. As +we tackle more complicated problems and our code grows to be more complex, we +are likely to forget what badly named variables originally stood for and what +their purpose was. Non-descriptive names make our code error-prone. **Great code +reads like English and almost explains itself.** As programmers, our goal is to +write code that is not only "correct", but also elegant, readable, and +maintainable! Hold yourself to this high standard. + +As far as syntax goes in JavaScript we always name our functions and variables +`camelCase` for multiple words. (Ex: `tipCalculator`, `currentNumber`, +`puppyPartyFinder`). Other languages use other conventions so it's best to pick +up the standard for your chosen language and stick with it. + +## Review + +By writing a function we can reuse code over and over again to solve similar +problems with different input data (arguments). This will make your life easier +and allow you to start working on more complex problems. + +This reading covered: + +- How to define and invoke a function in JavaScript. +- How to use the `return` keyword to return a value from a function. +- Writing readable JavaScript code by using significant names and following + `camelCase` conventions for multiple word variables and functions + +________________________________________________________________________________ +# Parameters and Arguments + +When talking about functions one of the first things we mentioned was the word +_parameters_. In this reading we will be covering what exactly a parameter is - +as well as the differentiation between _parameters_ and _arguments_. + +When you finish this reading, you should be able to: + +1. Identify the difference between parameters and arguments. +2. Write a function that utilizes declared parameters. +3. Invoking a function with passed in arguments. + +## The difference between Parameters and Arguments + +Let's start off by talking about the difference between _arguments_ and +_parameters_ and how to identify which is which. + +1. **Parameters** are comma separated variables specified as part of a + function's declaration. +2. **Arguments** are values passed to the function when it is invoked. + +So by defining _parameters_ when we declare our function we are effectively +setting accessible variables within the function: + +```js +function add(firstParameter, secondParameter) { + console.log(firstParameter + secondParameter); +} + +// the add function declares two parameters +> add(1, 2); //=> 3 +``` + +In the above example we declared our parameters when we declared our function. +Now _arguments_ work slightly differently - when the function is invoked we are +passing in _arguments_. So in the above example when we invoked `add(1, 2)` the +`(1,2)` were the _arguments_ being passed in. So when a function is invoked the +value of the declared parameters is assigned to the passed in _arguments_. + +You can think of it _parameters_ and _arguments_ like a recipe. A recipe is a +list of ingredients (_parameters_) and list of steps (the code to be run). When +someone cooks the recipe (_invokes_ the function) they add the ingredients they +actually have(_arguments_). The result of cooking the recipe is the delicious +`return` value! + +### Extra arguments + +In JavaScript a function will not throw an error if the number of _arguments_ +passed during a function invocation is different than the number of parameters +listed during function declaration. This is very important to know! + +Let's use the above function to demonstrate: + +```js +function add(firstParameter, secondParameter) { + console.log(firstParameter + secondParameter); +} + +// this will ignore the 17 & 14 +// the first two arguments passed in will be assigned to the first two parameters +> add(1, 2, 17, 14); //=> 3 +``` + +Notice in the above example we passed in 4 arguments (1, 2, 17, 14) to `add`. +Since the function was only looking for two parameters that is all it uses. + +### Not enough arguments + +Now what happens if we pass in less arguments then needed? + +```js +function add(firstParameter, secondParameter) { + console.log(firstParameter + secondParameter); +} + +> add(5); //=> NaN +``` + +Whoa what happened there? Let's do a play-by-play: + +1. `firstParameter` was set to equal the first passed in argument which in the + above case is 5. +2. Since there is no second argument then `secondParameter` is declared as a + variable but is set to the default value of `undefined`. +3. The function then tries to add 5 to `undefined` which is definitely not a + number! So we get `NaN` (which means `Not A Number`) printed to the console. + +As you write more functions you'll grow very comfortable using both arguments +and parameters to accomplish your function's goal. + +## Review + +- Parameters are variables defined as a part of a function's declaration. +- Arguments are values passed to the function when it is invoked. +- JavaScript functions can intake a different number of arguments than the + number of parameters listed during function declaration. + +________________________________________________________________________________ +# WEEK-01 DAY-2
*Control Flow* {ignore=true} +________________________________________________________________________________ +# Control Flow and Array Learning Objectives + +Below is a complete list of the terminal learning objectives for this lesson. +When you complete this lesson, you should be able to perform each of the +following objectives. These objectives capture how you may be evaluated on the +assessment for this lesson. + +1. Define a function that accepts a sentence string and two words as args. The + function should return a boolean indicating if the sentence includes either + word. +2. Identify a pair of mutually exclusive conditions +3. Given a for loop, translate it into a while loop, and vice-versa +4. Write a function that iterates through a provided string argument +5. Given a description of pig latin, write a function that takes in a string + argument and utilizes String#slice to translate the string into pig latin. +6. Write a function that takes in an array of words and a string as arguments + and returns a boolean indicating whether the string is located inside of the + array. The function must use Array#indexOf. +7. Define that an array literal is an ordered list of values defined by using + bracket and individual values are read by indexing. +8. Prevent code that can throw an exception from causing the program to crash. the terminal learning objectives for this lesson. +When you complete this lesson, you should be able to perform each of the +following objectives. These objectives capture how you may be evaluated on the +assessment for this lesson. + +1. Define a function that accepts a sentence string and two words as args. The + function should return a boolean indicating if the sentence includes either + word. +2. Identify a pair of mutually exclusive conditions +3. Given a for loop, translate it into a while loop, and vice-versa +4. Write a function that iterates through a provided string argument +5. Given a description of pig latin, write a function that takes in a string + argument and utilizes String#slice to translate the string into pig latin. +6. Write a function that takes in an array of words and a string as arguments + and returns a boolean indicating whether the string is located inside of the + array. The function must use Array#indexOf. +7. Define that an array literal is an ordered list of values defined by using + bracket and individual values are read by indexing. +8. Prevent code that can throw an exception from causing the program to crash. + +________________________________________________________________________________ +# Control Flow - Conditional Statements + +So far the code you've written has been pretty direct in it's intent. You can +define functions and variables but, so far the functions you've created haven't +been able to do that much for you _yet_. It's time to start writing functions +that can do things _conditionally_ by utilizing _control flow_. + +In simple terms - **control flow** is the order in which instructions are +executed within a program. One modifies control flow using _control structures_, +expressions that alter the control flow based on given parameters. The control +structures within JavaScript allow the program flow to change within a unit of +code or a function. + +This reading will be covering one of the two main _control structures_ you +will use time and time again - _Conditional statements_. _Conditional +statements_ are used to perform different actions based on different conditions. + +When you finish this reading, you should be able to: + +- Write `if`, `else if`, `if...else` conditional statements. +- Know that conditional statements can have only one `if` and one `else` + statement. +- Identify that conditional statements can be nested. + +## A Quick Word on Syntax + +Before we get started we'll quickly go over the terms we'll be using to +represent syntax. + +1. `[ ]` are square **brackets** +2. `{ }` are curly **braces** +3. `( )` are **parentheses** + +## Writing Conditional Statements + +Conditional Statements are the second fundamental _control structure_ for +writing JavaScript and are pretty straight forward. The simplest conditional +statement is the `if` statement. An `if` statement has two parts, the _test +expression_ (the code that immediately follows the `if` which goes in +parentheses), and the _then expression_ (this code belongs in braces after the +`if` expression). The _then_ expression will only run when the `if` expression +is truthy. + +Here is an example of a simple `if` statement: + +```js +// this is the test expression +if (3 === 3) { + // this is the then expression + // this code will run if the above statement is true + console.log("this is a three!"); +} +``` + +The `if` statement above allows you to specify what should happen if your +particular expression evaluates to true. You can chain additional _test +expressions_ onto this `if` statement by using a `else if` statement. + +The syntax for `else if` is very similar as an `if` statement: + +```js +function mathFun() { + let x = 2 + 3; + + if (x === 3) { + console.log("we have a 3"); + } else if (x === 4) { + // this code will run if the above statement is true + console.log("we have a 4"); + } else if (x === 5) { + // this code will run if the above statement is true + console.log("we have a 5"); + } +}; + +mathFun(); // => "we have a 5" +``` + +The `else if` and `if` statements do not, however, provide the option to specify +something else that should happen in the event that all of the above expressions +evaluate to be `falsey`. The `if...else` statement reads just like English. The +JS interpreter will execute the `else` statement if all the above conditions +given are `falsey`. See below for an example: + +```js +function mathFun() { + let x = 19; + if (x === 3) { + console.log("we have a 3"); + } else if (x === 4) { + console.log("we have a 4"); + } else { + console.log("I will return if everything above me is falsey!"); + } +}; + +mathFun(); // => "I will return if everything above me is falsey!" +``` + +You can chain an arbitrary number of `else if` statements but there can only be +one `if` statement and one optional `else` statement. The `if` introduces the control +structure and the `else` acts as a fail safe to catch everything that didn't +meet the above conditions. + +Only one _then expression_ is ever executed in an `if`, `if...else`, or +`if...else` statement. If one of the _test expressions_ is truthy, then the +result of its _then expression_ is the result of the **entire** conditional +statement: + +```js +let x = 3; +if (x === 3) { + console.log("this will run"); +} else { + console.log("this will not run"); +} +``` + +Additionally, you can nest conditional statements within each other but it will +get hard to read pretty quickly and is discouraged: + +```js +function mathFun(x) { + if (x === "math") { + if (x === "math" && x[0] === "m") { + if (x[1] === "a") { + console.log("this got confusing fast"); + } else { + console.log("that is not math!"); + } + } else { + console.log("that is for sure not math!"); + } + } else { + console.log("I will return if everything above me is false!"); + } +}; + +mathFun("math"); // => "this got confusing fast" +``` + +## Review + +- Conditional statements allow us to control what actions should be taken based + on a boolean (truthy or falsey) expression +- In a chain of _then expressions_ (`if...else if...else`), only one of the + _then expressions_ will be executed. +- Conditional statements can have only one `if` and one `else` statement. +- Conditional statements can be nested. + +________________________________________________________________________________ +# Mutually Exclusive Conditions + +You have now learned how to write conditional statements. Now we'll talk a +little bit more about how to write them using best practices. + +When you finish this reading, you should be able to: + +- Identify a pair of mutually exclusive conditions. + +## When to use if statements + +Say you are given the challenge to write a function that that will call another +function named `bigNumber` if the given argument is **greater** than 100 or call +a function named `smallNumber` if it the given argument is smaller. You could +write a function to do that which would look like this: + +```js +function numberSeparator(number) { + if (number < 100) { + // number is smaller than 100 so we invoke smallNumber + smallNumber(); + } + if (number === 100) { + // number is equal to 100 so we invoke smallNumber + smallNumber(); + } + if (number > 100) { + // number is larger than 100 so we invoke bigNumber + bigNumber(); + } +} +``` + +As you can probably tell the above function uses a lot of code to do a simple +task. To be clear the function above would work for our aim - but it repeats +itself. There is an age old principal for writing good code named **DRY** or +**Don't repeat yourself**. As good programmers we always want our code to be +clear, concise, and efficient. + +A general rule of thumb is that if you are working with a condition that is +**mutually exclusive**, meaning if one condition is true the other condition +must be false, then you should use an `if/else` statement. You can also think of +**mutually exclusivity** like a coin flip - it can be either heads or tails but +not both. + +Going back to the original problem at hand we can see it makes intuitive sense +with the way the challenge is phrased: If the number is larger than 100 then +we'll call `bigNumber`, otherwise we invoke is `smallNumber`. + +So let's rewrite the above function to read a little more clearly: + +```js +function numberSeparator(number) { + if (number > 100) { + bigNumber(); + } else { + smallNumber(); + } +} + +// this also works +function numberSeparator(number) { + if (number <= 100) { + smallNumber(); + } else { + bigNumber(); + } +} +``` + +Look at how much clearer that is! Writing good code is an art - devote yourself +to becoming an artist! + +## Review + +- How to identify a pair of mutually exclusive conditions. +- DRY - don't repeat yourself! + +________________________________________________________________________________ +# Control Flow - Looping + +A quick reminder before we start - **control flow** is the order in which +instructions are executed within a program. One modifies control flow using +_control structures_, expressions that alter the control flow based on given +parameters. This reading will be covering the second of the main _control +structures_ you will use time and time again - _loops_. + +When you finish this reading, you should be able to: + +1. Know how to write a `while` loop and a `for` loop. + - Know how to convert a `for` loop into a `while` loop +2. Know that index variables conventionally start at zero. +3. Explain what an _iteration_ is. + +## Looping + +Imagine you are at a friend's house and your friend has six dogs. Someone left +the back gate open and all the dogs go out in the yard and get super muddy. Now +your friend wants to clean their dogs but they only have one bathtub! You can't +wash all the dogs at once. So the only option is to give the dogs a bath one at +a time until they are all clean. When you start 0 dogs are clean and 6 dogs are +dirty. + +_While_ there are still dirty dogs you still have a job to do. That is your +**condition** - you will stop giving baths once all 6 dogs are clean. So after +one bath you you have 1 clean dog and 5 dirty dogs. You've +_incremented_(increased by one) your number of clean dogs. After each bath you +check your **condition** again until you have 6 clean dogs so you know you can +stop! + +What we've described above is the idea of looping - setting a condition, +executing an action, doing something to make sure our condition will be met +eventually, and rechecking our condition before executing our next action. + +Loops are a fundamental _control structure_ for writing JavaScript. +Loops will repeatedly execute a section of code while a condition is true. Loops +are simple to write and incredibly powerful! There are many variations of loop +but we will be covering the two most fundamental loops now - **while** loops and +**for** loops. + +### While Loops + +One of the simplest loops in `JavaScript` is the `while` loop. As with all +loops, the `while` loop will execute a block of code as long as a specified +condition is true. The while loop starts with the keyword `while` then states a +condition in parentheses. The code in the following braces will be run until the +above condition is met. + +```js +while (condition) { + // code block to be executed +} +``` + +In the following example, the code in the loop will run, over and over again, as +long as a variable (`index`) is less than 10: + +```js +let index = 0; + +// this is the condition that will be checked every time this loop is run +while (index < 10) { + console.log("The number is " + index); + // this is common shorthand for index = index + 1 + index++; +} +``` + +The most important thing to remember when writing any loop is to always be +working towards your condition. In the example above if we did not increment the +`index` variable by 1 each time the loop ran then we would be stuck with what we +call an **infinite loop**: + +```js +let index = 0; + +// this is an infinite loop because our condition will never be met +while (index < 10) { + console.log("The number is " + index); + // if we do not increase the index then our condition is never met + // Meaning this will run forever! +} +``` + +The above code will run until whatever interpreter you are using crashes. + +### Important Loop Knowledge + +A quick word before we learn about the next loop. + +The _index_ is the traditional word for the variable that keeps track of how +many times the loop has been run. Don't write loops with indices starting at +one; you'll confuse other programmers and yourself. Indices have started at zero +for a long time, and for good reason. It's much easier to use loops that start +with an index of zero because Array and String indices also start at zero. + +```js +let array = [0, 1, 2]; +let index = 0; + +while (index < array.length) { + console.log( + "Both the index and the current array position are " + array[index] + ); + index++; +} +``` + +In the above code we will do one loop for each digit in the Array above. We call +each of those loops an "iteration". An iteration is the act of repeating a +procedure, hence looping is an **iterative** technique. Each repetition itself +is also called an "iteration." So you can use loops to _iterate_ through Arrays +and Strings. + +### For Loops + +A `for` loop can be broken down into three sections: + +1. The _initial expression_ which will be run once at the beginning of the loop. +2. The _condition_ which is checked every time the loop is run. If this + condition is true the loop will run again. If this condition is false the + loop will end. +3. The _loopEnd expression_ which will be run at the end of the loop before + checking the _condition_ again. + +```js +for (;;) +``` + +The `for` loop is usually used with an integer counter: + +```js +for (let index = 0; index < 10; index += 1) { + // the code inside this block will run 10 times +} +``` + +While the _loopEnd expression_ is normally used to increase a variable by one +per loop iteration, it can contain any statement, such as one that decreasing +the counter, or increasing it by 2. + +You can use the `for` loop to iterate through all kinds of things. Check out the +example below for how to iterate through a String: + +```js +let testString = "testing"; + +// we can use the testString's length as our condition! +// Since we know the testString's index starts at 0 +// and our index starts at 0 we can access each letter: +for (let index = 0; index < testString.length; index += 1) { + let letter = testString[index]; + console.log(letter); +} +``` + +These are the most basic types of loops. If all else fails, you can always fall +back on these two loops. All the other loop forms are just more convenient forms +of these basic loop styles. + +## Translating From One Loop to Another + +So far we have covered both `while` and `for` loops. Once you understand the +concept of looping it's easy to translate one loop to another: + +```js +// these two do the exact same thing! +function forLoopDoubler (array) { + // it is convention to shorten index to just i in most cases + for (let i = 0; i < array.length; i++) { + array[i] = array[i] * 2; + } + return array; +}; + +function forLoopDoubler (array) { + let i = 0; + while (i < array.length) { + array[i] = array[i] * 2; + i++; + } + return array; +}; + +forLoopDoubler([1, 2, 3]); // => [2,4,6] +whileLoopDoubler([1, 2, 3]); //=> [2,4,6] +``` + +## Review + +- We can use a `for` or `while` loop to repeat a block of code repeatedly. +- While the loop condition is true, we will execute another iteration of the + loop. +- When the loop condition is false, we will exit the loop. + +________________________________________________________________________________ +# The Array Type + +This reading will be about one of JavaScript's global objects, the **Array** +type. JavaScript arrays are used to store multiple values all within a single +structure, much like a creating a list. Arrays can hold strings, integers and +even other arrays! Arrays are incredibly useful for holding a bunch of different +information all in one place. + +When you finish this reading, you should be able to: + +- Write arrays using correct syntax +- Identify that an array is an ordered list of values defined by using brackets +- Use `.length` to obtain a count of the numbers of elements that comprise an + array +- Index an array to refer to a single value +- Concatenate multiple arrays together + +## Using arrays + +While coding you will find that you often find yourself needing to refer to a +bunch of data at once. For instance, what if you wanted to refer to the entire +English alphabet. Sure, you could create a bunch variables for each letter in +the alphabet: + +```js +let a = "a"; +let b = "b"; +let c = "c"; +let d = "d"; +// and so on for way too long... +``` + +However this becomes cumbersome and unmanageable quickly. An Array is a data +structure that solves this problem. Arrays are always wrapped in square +brackets, `[]`, and store their comma separated values in sequential order. +Arrays in JavaScript are also very flexible: we can put elements into an array, +replace elements in an array, and remove elements from the array. + +So going back to our first example of containing the alphabet: + +```js +let alphabet = [ + "a", "b", "c", "d", "e", "f", + "g", "h", "i", "j", "k", "l", + "m", "n", "o", "p", "q", "r", + "s", "t", "u", "v", "w", "x", + "y", "z" +]; +``` + +## Indexing arrays + +### Calculating the length of an array + +Since an array can container any number of values you will find it useful to +count the number of values available to you using `.length`: + +```js +console.log([4, 7, 9].length); // => 3 +console.log([1, 2].length); // => 2 +console.log([].length); // => 0 +``` + +### Properly indexing an array + +Arrays consist of multiple values all stored in sequential order. These value +are numbered by **indices** starting at 0 (just like indexing a string!). So +given the below example: + +```js +let numbersAndLetters = ["b", "z", 17, "cat"]; +``` + +In the above `numbersAndLetters` array if we access `numbersAndLetters` at the +index of 0 we get back the value of "b". If we access `numbersAndLetters` at the +index of 1 we get "z", at the index of 3 we get 17, etc. We can specify which +value we'd like to access in an array by using square brackets,`[]`, and +specifying an index: + +```js +console.log(numbersAndLetters[0]); // => "b" +console.log(numbersAndLetters[1]); // => "z" +console.log(numbersAndLetters[2]); // => 17 +console.log(numbersAndLetters[3]); // => "cat" +``` + +Notice that even though the index at `numbersAndLetters[3]` has the value of a +string with multiple characters ("cat") we return the _entire value_ listed at +that index. + +**Reminder:** Arrays **always** start at the index of 0, not 1. This is the +convention in programming. Additionally, indices should always be a number. + +We can access a value in an array directly by providing an index for the value +we'd like to access in that array (`array[index]`). See below for an example: + +```js +console.log(["a", "b", "c"][0]); // => "a" +console.log(["a", "b", "c"][1]); // => "b" +console.log(["a", "b", "c"][2]); // => "c" +console.log(["a", "b", "c"][3]); // => `undefined` +``` + +As we see in the code above, if we try to access an element at an index that is +not inside the array, we get back `undefined`. This makes sense because there is +no value at that given position! + +### The classic "off by one" error + +Arrays are similar to strings in that both of their indices start at 0 instead +of 1. Forgetting this fact can lead to some pretty confusing situations. Let's +focus on an important distinction: the index of the last value of an array is +always one less than its length. + +```javascript +console.log([4, 7, 9].length); // => 3 +console.log([4, 7, 9][3]); // => undefined +console.log([4, 7, 9][2]); // => 9 +``` + +In other words, although the `length` of `[4, 7, 9]` is 3, the index of the last +value (`9`) is 2. A good rule of thumb of accessing the last index of an array +is to find the length and then subtract one: + +```js +let testArray = [4, 7, 9]; +let finalIndex = testArray.length - 1; // => (3 - 1) = 2 +console.log(testArray[finalIndex]); // => 9 +``` + +## Working with arrays + +### Containing data in arrays + +By packaging groups of related data into a single array, we gain the added +benefit of being able to refer to that data as a single collection. Arrays don't +have to just hold single characters- they are capable of holding entire strings, +numbers, and even other arrays! + +```js +let wackyArray = [2, 17, "apple", "cat", ["apple"]]; + +console.log(wackyArray[0]); // => 2 +console.log(wackyArray[1]); // => 17 +console.log(wackyArray[3]); // => "cat" +console.log(wackyArray[4]); // => ["apple"] +``` + +Just think of all the possibilities of what you can store in a single array! +However, just because you can _doesn't_ mean you should. In practice we will +almost always be storing similar kinds of data, that are coming from a common +source (i.e. items in a shopping list, ID numbers, tasks on a todo list). + +### Using indexOf with arrays + +We can also calculate the index of a given value within an array by using +`indexOf`: + +```javascript +console.log([1, 3, 5, "apple", "jet"].indexOf(3)); // => 1 +console.log([1, 3, 5, "apple", "jet"].indexOf(5)); // => 2 +console.log([1, 3, 5, "apple", "jet"].indexOf("jet")); // => 4 + +// this won't be found in the array +console.log([1, 3, 5, "apple", "jet"].indexOf("potato")); // => -1 +``` + +If we attempt to search for a value that is **not** present in an array, +`indexOf` will return -1. This makes sense because we know that -1 is not a +valid array index. The smallest index possible is 0! + +## Concatenation with arrays + +As a reminder, concatenation is just a fancy word for joining things together +into a single collection. Now, this is where arrays will differ from strings. +The `+` operator only exists for numbers and strings. If you try to use the `+` +on an array it will try to help you out by _converting your arrays into +strings_. + +```js +console.log([1, 2, 3] + [4, 5, 6]); // => 1,2,34,5,6 +``` + +JavaScript was just trying to help! However that is probably not what you meant +to do. Good thing JavaScript has a seperate method for putting two array +together. To concatenate arrays, we can use the aptly named `.concat` method: + +```javascript +console.log([1, 2, 3].concat([4, 5, 6])); // => [1, 2, 3, 4, 5, 6] +``` + +## What you've learned + +- An **Array** is a data type that contains a list of in order values surrounded + in square brackets `[]`. +- `array.length` returns the number of values in the `array`. +- Each value of an array is associated with a number index; the first value of + an array is at the index of 0. +- We can use `array.indexOf(value)` to obtain the index of `value` within + `array`; if `value` is not found, then -1 is returned. +- We can use `.concat` to concatenate multiple arrays, combining them into a + single array. + +________________________________________________________________________________ +# WEEK-01 DAY-3
*Intermediate Functions* {ignore=true} +________________________________________________________________________________ +# Intermediate Functions Learning Objectives + +Below is a complete list of the terminal learning objectives across all +"Intermediate Function" lessons. When you complete these lessons, you should be +able to perform each of the following objectives. These objectives capture how +you may be evaluated on the assessment for these lessons. + +1. Identify that strings are immutable and arrays are mutable +2. Define a function using both function declaration and function expression + syntax +3. Utilize Array#push, #pop, #shift, #unshift to mutate an array +4. List the arguments that can be used with Array#splice +5. Write a function that sums up elements of an array, given an array of numbers + as an argument +6. Utilize Array#forEach, #map, #filter, #reduce in a function +7. Define a function that takes in an array of numbers and returns a new array + containing only the primes +8. Define a function that takes in a 2D array of numbers and returns the total + sum of all elements in the array +9. Define a function that takes in an array of elements and returns a 2d array + where the subarrays represent unique pairs of elements +10. Define a function that takes in an array of numbers as an argument and + returns the smallest value in the array; if the array is empty return null the terminal learning objectives across all +"Intermediate Function" lessons. When you complete these lessons, you should be +able to perform each of the following objectives. These objectives capture how +you may be evaluated on the assessment for these lessons. + +1. Identify that strings are immutable and arrays are mutable +2. Define a function using both function declaration and function expression + syntax +3. Utilize Array#push, #pop, #shift, #unshift to mutate an array +4. List the arguments that can be used with Array#splice +5. Write a function that sums up elements of an array, given an array of numbers + as an argument +6. Utilize Array#forEach, #map, #filter, #reduce in a function +7. Define a function that takes in an array of numbers and returns a new array + containing only the primes +8. Define a function that takes in a 2D array of numbers and returns the total + sum of all elements in the array +9. Define a function that takes in an array of elements and returns a 2d array + where the subarrays represent unique pairs of elements +10. Define a function that takes in an array of numbers as an argument and + returns the smallest value in the array; if the array is empty return null + +________________________________________________________________________________ +# Function Expressions + +You may have noticed that we've been writing many functions so far in the +course! We will continue to do so since functions are the building blocks of the +eventual applications that we will build. That being said, let's begin to +broaden the way we think about functions. In particular, we'll want think of +functions as expressions that we can store in variables - just like our classic +data types of number, string, boolean, array, and object! + +When you finish this article, you should be able to: + +- identify functions as first-class objects in JavaScript +- define a function using function expression syntax + +## Functions as first-class objects + +JavaScript is well known for being a programming language that treats functions +as "first-class objects". This fancy talk means that you can treat a function as +a "normal" value by storing it in a variable. We'll leverage this key concept in +very clever ways later in the course. For now, let's begin with a simple example +that shows the "first-class object" nature of functions: + +```javascript +let calculateAverage = function(a, b) { + return (a + b) / 2; +}; + +console.log(calculateAverage(10, 20)); // 15 +``` + +In the code snippet above, we define the `calculateAverage` by assigning a +variable to contain the function's definition. By doing this, the variable's +name is effectively the function's name. So to call the function, we simply +refer to the variable name. Note that we do not write the function's name after +the `function` keyword, where we normally would. We will refer to this new way +of defining functions as _function expression syntax_ and the classic way of +defining functions as _function declaration syntax_. In general, we can define +functions using either syntax: + +```javascript +// function declaration syntax +function myFunctionName(arg1, arg2) {} + +// function expression syntax +let myFunctionName = function(arg1, arg2) {}; +``` + +In the coming sections, we'll highlight moments when we'll prefer one syntax +over the other. For now, get acquainted with the new syntax as it is something +you'll be seeing a lot of as a programmer! + +### A peek under the hood + +Perhaps you're finding it tough to understand what it means for a variable to +contain a function - it is indeed a very abstract idea for new programmers. +Let's draw a comparison. We know that when we assign an expression to variable, +the expression first evaluates to a single value, which we then store in the +variable name: + +```javascript +let myNum = 4 + 4; +console.log(myNum); // prints 8 +console.log(myNum * 3); // prints 24 +``` + +In the same way we can treat a function definition as an expression that +evaluates! + +```javascript +let myFunc = function() { + console.log("I'm a function"); +}; + +console.log(myFunc); // prints [Function: myFunc] +myFunc(); // prints "I'm a function" +``` + +Looking at the snippet immediately above, you'll notice that when we print the +`myFunc` variable directly, without calling the function with parentheses, +JavaScript simply says the variable contains a function named myFunc +(`[Function: myFunc]`). You can truly imagine a function as a value that we can +store and use as we please. + +> The term _anonymous function_ may also be used to describe a function +> expression before it is assigned to any variable. Following the example above, +> we'll use the word _anonymous function_ to describe the function expression +> _before_ the assignment to the `myFunc` variable is complete. Once the +> assignment is complete, it would be silly to refer to `myFunc` as an +> `anonymous function` because an _anonymous function_ has no name. + +## What you've learned + +- functions can be stored in variables; just like any other values in + JavaScript! + +________________________________________________________________________________ +# Two-Dimensional Arrays (2D Arrays) + +Time to broaden our understanding of arrays! We've already explore the +fundamentals of arrays. Mainly, we can store any type of data we please as +elements of an array and even mix types together. However, what happens if we +store an array as an element of an array? + +When you finish this article, you should be able to: + +- index into the inner elements of a 2D array +- use nested loops to iterate through a 2D array + +## Multidimensional Arrays + +When we store arrays as elements of other arrays, we refer to those structures +as multidimensional arrays. If the "depth" of the nested arrays is at exactly 2 (an +outer array containing inner arrays), then we'll refer to it as a +two-dimensional array: + +```javascript +let twoDimensional = [["a", "b", "c"], ["d", "e"], ["f", "g", "h"]]; + +console.log(twoDimensional[1]); // [ 'd', 'e' ] +console.log(twoDimensional[1][0]); // 'd' + +let subArr = twoDimensional[1]; +console.log(subArr[0]); // 'd' +``` + +Note that indexing the outer `twoDimensional` array will return an element like +usual, it's just that element happens to be another array. To gain access to the +innermost elements, we simply need to apply another set of indexing brackets! + +If we style our 2D arrays nicely so that each subarray is on a new line, we can +interpret the double indices as `[row][column]`: + +```javascript +let twoDimensional = [ + ["a", "b", "c"], + ["d", "e"], + ["f", "g", "h"]]; + +// get the element in the 0th row, 2nd col: +console.log(twoDimensional[0][2]); // 'c' +``` + +## Iterating through 2D Arrays + +Since a 2D array is just an array of arrays. We'll need to use a loop within a +loop to iterate through a 2D array: + +```javascript +let array = [["a", "b", "c"], ["d", "e"], ["f", "g", "h"]]; + +for (let i = 0; i < array.length; i++) { + let subArray = array[i]; + console.log(subArray); + + for (let j = 0; j < subArray.length; j++) { + console.log(subArray[j]); + } +} +``` + +In the nested loops above, the `i` index refers to the current "row" and the `j` +index refers to the current "column". It's worth noting that since the inner +subArrays have different length, we'll want to specifically reference the length +of that subarray in our inner loop condition `j < subArray.length`. The code +above will print: + +```plaintext +[ 'a', 'b', 'c' ] +a +b +c +[ 'd', 'e' ] +d +e +[ 'f', 'g', 'h' ] +f +g +h +``` + +## When is a 2D array practical? + +As a preview of things to come let's briefly mention when you'll find a 2D array +useful in your future projects. Imagine how'd you represent a "grid": + +- tic-tac-toe (3x3 grid) +- chess (8x8 grid) +- sudoku (9x9 grid) +- excel (a sheet is an arbitrarily sized 2D array) + +## What you've learned + +- an array can contain arrays as elements, we call this a 2D arrays +- to iterate through a 2D array, used nested loops + +________________________________________________________________________________ +# Mutability in JavaScript + +So far in the course we've explored a handful of methods that manipulate data. +We'll be growing our arsenal of methods further overtime, so we'll want to gain +awareness for **exactly** how we should expect these methods to manipulate the +data we give them. To this end, let's analyze which methods will modify existing +data and which methods do not. We refer to this concept as **mutability**. + +When you finish this article, you should be able to: + +- Explain what "mutability" is +- Correctly label JavaScript data types as immutable or mutable + +## What is mutability? + +At its face value, _mutability_ is a simple concept. You may be familiar with +the word _mutation_, which refers to a alteration (usually in DNA). Something +that is _mutable_ can be changed, while something that is _immutable_ is +unchanging and permanent. To illustrate this concept, we'll begin with strings +and arrays. We've spent some time with these two data types and by now we +recognize that the two types share many similarities. Both have indices, +`length`, and even share common methods like `slice`. However, they differ +greatly in their mutability: + +```javascript +let myArr = ["b", "e", "a", "m"]; +myArr[0] = "s"; +console.log(myArr); // 'seam' + +let myStr = "beam"; +myStr[0] = "s"; +console.log(myStr); // 'beam' +``` + +Above we have shown that we can assign a new element to an index of an array, +but we cannot assign a new character to an index of a string. In other words, +arrays are _mutable_, but strings are _immutable_. + +An implication of this discovery is that there are _some_ array methods that +will modify an existing array but _zero_ methods that will modify an existing +string. Methods that manipulate string data typically return a _new_ string and +never modify an existing one. A prime example is `toUpperCase`: + +```javascript +let word = "piñata"; +let newWord = word.toUpperCase(); +console.log(word); // 'piñata' +console.log(newWord); // 'PIÑATA' +``` + +Above, notice that the `toUpperCase` method returns a capitalized version of the +string, but does not change the original string. It's also worth noting that not +every array method will mutate. For example, the `slice` method does not mutate +for both strings and arrays. As we learn about methods in the future, we'll be +certain to note what mutates and what does not. + +## Mutable or immutable, that is the question + +Now that we have a grasp of _mutability_, let's take inventory and identify +JavaScript's data types as mutable or immutable. + +**Mutable** + +- array +- object (we'll learn these soon) + +**Immutable** + +- number +- string +- boolean + +A quick way to remember the above list is to identify that the composite types +(the types that can contain multiple values) of array and object are mutable. +The remaining "simpler" types of number, string, and boolean are immutable. + +## The mutability misconception + +Maybe you are having a tough time believing what we have just claimed. We don't +blame you, you've probably heard the saying that change is the only constant in +the universe. Let's debunk a common argument to turn you into a believer. The +skeptical programmer may use this as an argument to show that numbers are +mutable: + +```javascript +let myNum = 42; +myNum += 8; +console.log(myNum); // 50 +``` + +Because the `myNum` variable now contains `50` where it once contained `42`, it +may seem we have mutated the number, but this is not truly the case. Recall that +`myNum += 8` is shorthand for `myNum = myNum + 8`. Since the right hand side of +the assignment evaluates first, we are simply taking the new number of `50` and +reassigning it to the `myNum` variable. This reassignment of a variable name is +not a mutation of the original number. + +## What you've learned + +- data types that can be changed are mutable, those that cannot be changed are + immutable +- arrays and objects are mutable +- numbers, strings, and booleans are immutable + +________________________________________________________________________________ +# Array Splice + +Time to a learn yet another array method! The [Array#splice][mdn-splice] method +deserves its own reading because of how versatile it is. Feel free to use this +article as a quick reference; let's jump right in. + +When you finish reading this article, you should be able to: + +- list all possible arguments that can be used with the `Array#splice` method + +## Notation + +For clarity in this article and moving forward in the course, we'll be notating +methods with `#` to clarify how they should be called. For example, +`Array#splice` refers to the method that should be called on an array, +`arr.splice()` where `arr` is some array variable. Likewise `String#toUpperCase` +refers to the method that should be called on a string, `str.toUpperCase()` +where `str` is some string variable. We'll opt to refer to methods using this +notation because some methods can be called on multiple data types, such as +`Array#slice` and `String#slice`. + +## What can Array#splice do? + +Before we explore the nitty-gritty details of the `Array#splice` method, the +first thing to be aware of is that the method will **mutate** the array that it +is called on. That is, `Array#splice` will modify the existing array and _not_ +return a new array. + +### Using splice to remove + +The usage of the `Array#splice` method is easy to mix up because it can be used +to remove or insert elements into an array. That's right - it can perform +"opposite" operations, even at the same time! For now, we'll begin by _only_ +removing elements from an array: + +```javascript +let colors = ["red", "yellow", "blue", "green", "orange", "brown", "gray"]; +let returnVal = colors.splice(2, 3); +console.log(colors); // [ 'red', 'yellow', 'brown', 'gray' ] +console.log(returnVal); // [ 'blue', 'green', 'orange' ] +``` + +The first two arguments for splice correspond to 1) the target index and 2) how +many elements to remove. The call `colors.splice(2, 3)`, will remove the next +three elements beginning at index 2. This means that the elements at indices 2, +3, and 4 are removed. + +Note that splice returns an array containing the elements that were removed and +also has the effect of removing the elements from the _original_ array, mutating +it in-place. + +### Using splice to insert + +To use the splice method to insert new elements into an array, we can pass in +any number of additional arguments representing the values to insert: + +```javascript +let colors = ["red", "yellow", "blue"]; +let returnVal = colors.splice(1, 0, "RebeccaPurple", "CornflowerBlue"); +console.log(colors); // [ 'red', 'RebeccaPurple', 'CornflowerBlue', 'yellow', 'blue' ] +console.log(returnVal); // [] +``` + +The method call `colors.splice(1, 0, 'RebeccaPurple', 'CornflowerBlue')` +translates to "target index 1, remove the next 0 elements, then insert +`'RebeccaPurple'` and `'CornflowerBlue'`." + +### Using splice like a pro + +Naturally, we can combine these two functionalities! Say we wanted to target +index 2, remove the next 3 elements, then insert `'Gainsboro'`, `'Ivory'`, and +`'Khaki'`: + +```javascript +let colors = ["red", "yellow", "blue", "green", "black", "beige"]; +let removed = colors.splice(2, 3, "Gainsboro", "Ivory", "Khaki"); +console.log(colors); // [ 'red', 'yellow', 'Gainsboro', 'Ivory', 'Khaki', 'beige' ] +console.log(removed); // [ 'blue', 'green', 'black' ] +``` + +Bam. What a versatile method! Always feel free to reference the +[documentation][mdn-splice] for the method when you are struggling to remember +its usage: + +## What you've learned + +- Array#splice has two required arguments + - the target index + - the number of elements to remove beginning at that target index +- Array#splice can also take in any number of values to be inserted at the + target index + +[mdn-splice]: + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice + +________________________________________________________________________________ +# String#split and Array#join + +We've seen previously that strings and arrays share many similar properties. For +example, strings and arrays both have a `length` and can have multiple indices. +Because of this, you may find it useful to "convert" between the two types. + +When you finish this article, you should be able to: + +- use the `String#split` method to turn a string into an array +- use the `Array#join` method to turn an array into a string + +## String#split + +The [String#split][string-split-mdn] method is called on a string and accepts a +"separator" string as an argument. The method will return an array where the +elements are the resulting substrings when we cut at the "separators": + +```javascript +let sentence = "follow the yellow brick road"; +let words = sentence.split(" "); +console.log(words); // [ 'follow', 'the', 'yellow', 'brick', 'road' ] +console.log(sentence); // 'follow the yellow brick road' +``` + +Note that the original string is _not mutated_, rather a new array is returned. +A common pattern is to split a sentence string on a space (' '), but you can +split on any separator as you see fit: + +```javascript +let sentence = "follow the yellow brick road"; +console.log(sentence.split(" ")); // [ 'follow', 'the', 'yellow', 'brick', 'road' ] +console.log(sentence.split("the")); // [ 'follow ', ' yellow brick road' ] +console.log(sentence.split("o")); // [ 'f', 'll', 'w the yell', 'w brick r', 'ad' ] +``` + +A pattern you may find useful is that when you split on a separator string, it +is guaranteed that that separator will not be in the resulting array, +effectively removing it. See the example of `sentence.split('the')` above. This +may come in handy, so keep it in mind! + +## Array#join + +The [Array#join][array-join-mdn] method is called on an array and accepts a +"separator" string as an argument. The method will return a string where +elements of the array are concatenated together with the "separator" between +each element: + +```javascript +let words = ["run", "around", "the", "block"]; +let sentence = words.join(" "); +console.log(sentence); // 'run around the block' +console.log(words); // [ 'run', 'around', 'the', 'block' ] + +console.log(words.join("_")); // 'run_around_the_block' +console.log(words.join("HI")); // 'runHIaroundHItheHIblock' +``` + +`Array#join` does not mutate the original array, instead it will return a new +string. + +## A clever combination + +It's pretty evident that `String#split` and `Array#join` are "opposite" methods. +That is: + +- we use split to turn a string into a array +- we use join to turn an array into a string + +By combining these two methods we can accomplish some cool behavior: + +```javascript +let str = "I don't know what I want to eat"; +let newStr = str.split("I").join("we"); +console.log(newStr); // 'we don't know what we want to eat' +``` + +Whoa! We were able to replace every substring "I" with the substring "we". We +know that the line `str.split('I').join('we')` evaluates from left to right. +This means that the `split` will cut the string wherever there is an 'I', +leaving a gap where the 'I's were. Then, the `join` will fill those gaps with +'we's. + +## What you've learned + +- we can use `String#split` and `Array#join` to convert between strings and + arrays +- both methods do not mutate their input + +[string-split-mdn]: + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split +[array-join-mdn]: + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join + +________________________________________________________________________________ +# WEEK-01 DAY-5
*Control Flow* {ignore=true} +________________________________________________________________________________ +# Determining Types + +Sometimes you want to know the type of value store in a variable so that you can +safely do things with it. If your function expects an array in its parameter but +gets a number, you can't call the `map` method on that! + +In this article you will learn how to figure out if a value in a variable is + +* A string +* A number +* A function +* An array + +## The typeof operator + +Not all operators in JavaScript require two arguments like the `+` operator for +addition, the `=` for assignment, and the `%` operator for modulo division. +Those are all called _binary_ operators because they take two (bi-) operands, +or things that are operated on. + +JavaScript kindly gives you the operator `typeof` which acts on a single value. +Operators that take only one operand are called _unary_ operators because "u +only give them one value!" (That's a joke. "uni-" or "una-" is one.) + +Here are some examples of what you'd expect to see with the `typeof` operator. + +```js +let s = 'This is a string'; +console.log(typeof s); // 'string' + +let n = 6.28; +console.log(typeof n); // 'number' + +let sum = function (a, b) { + return a + b; +} +console.log(typeof sum); // 'function' +``` + +Note that the value returned from the `typeof` operator is a String data type. +So, if you want to check if a value is a number, you could do this. + +```js +if (typeof n === 'number') { + // It is a number. Do some maths! +} else { + console.log('I really wanted a number. :-('); +} +``` + +## How to tell if a value is an array + +Unfortunately, due to a _really old bug_ in the way that JavaScript works, a bug +that no one can fix because people wrote code that relies on the bug for +decades, you cannot use the `typeof` operator to figure out if something is an +array. + +```js +let a = [1, 2, 3]; +console.log(typeof a); // 'object' +``` + +Gee, JavaScript. That's not helpful. Thanks. + +Luckily, it only took 12 years for JavaScript to include a way to test if a +value is an array. To do so, you use the `Array.isArray` method like this. + +```js +let a = [1, 2, 3]; +Array.isArray(a); // true + +let n = 6.28; +Array.isArray(n); // false + +let f = function () {} +Array.isArray(f); // false +``` + +## Practical use in "real" code + +Oddly enough, you won't see a lot of code in real-world applications testing if +a value is one type or another. A lot of JavaScript functions just _assume_ that +they will get arguments of the right kind because the parameter names imply what +kind of value to pass in. For example, the following function has a parameter +named `sentence`. + +```js +function reverseTheSentence(sentence) { + // ... code here ... +} +``` + +Most developers will know that the function probably wants `sentence` to be a +string value. They just won't pass in an array or number or ... well, anything +other than a string. Because that's just not polite. They'd expect any other +kind of value to cause the `reverseTheSentence` to malfunction. Only when you +know that people that don't respect your code will use it should you add in some +kind of check like this. + +```js +function reverseTheSentence(sentence) { + if (typeof sentence !== 'string') { + // Tell the developer they are using + // the function wrong. + } + // ... code here ... +} +``` + +## What you've seen + +This article has shown you two ways to determine if a value is a kind of type: + +* the `typeof` operator to use to test if a value is a number, a string, or + a function; and, +* the `Array.isArray` method to check if a value is an array. + +Use them as much (or as little) as you need! + +________________________________________________________________________________ +# The Null Type (And Undefined) + +You've met numbers and string, Booleans and arrays. There's another type often +used in JavaScript: the Null type. And, it's a special type. + +In this article, you will learn about the Null type, its value, and how to work +with it in JavaScript. + +## A type with only one value + +You have seen that the String type can have an "infinite" number of values +(within the limits of your computer memory). For example, the String type +represents _any_ of the following values. + +```js +// Examples of values with the String type +'hello, world' +"this is a string" +`Where is my pudding?` +'' +'A really long string.........................................................' +``` + +The Number type also has this aspect. Any number that you can reasonable express +in JavaScript has the Number type. + +```js +// Examples of values with the Number type +-100 +99 +6.28 +Infinity +``` + +You also know about the Boolean type. It can have only two values. + +```js +// The only two values of Boolean type +true +false +``` + +There are not _more_ Boolean values. You can't dream up more. There are only +two, those two. + +The Null type has one and exactly one value. + +```js +// The only value that has the Null type +null +``` + +It's just that word: `null`. No quotation marks. No other fancy things. Just +`null`. + +## The meaning of null + +This is a harder subject to tackle because it's a _philosophical_ subject. Many +people ask, "What does the value of `null` mean in a program?" There are a +couple of answers that programmers give to this. None of them are wrong. None of +them are right. They just are. In the presence of `null`, the code you write +determines which of the following meanings `null` has. + +* The value `null` means _the absence of a value_ or _no value_ +* The value `null` means _an unknown value_ +* The value `null` is a nuisance and I hate it and wish it were never invented + +During your software programming career, you will likely have all three of those +opinions, sometimes at the same time. Let's take a look at some examples to try +to figure this out. + +## The absence of a value + +Let's say you wrote a function that splits a string into words, reverses them, +and puts them back together in reverse order. You can do that with the methods + +* `String#split` [link][split]; +* `Array#reverse` [link][reverse]; and, +* `Array#join` [link][join]. + +That function could look like this. + +```js +function reverseTheSentence(sentence) { + let parts = sentence.split(' '); + parts.reverse(); + return parts.join(' '); +} +``` + +That's great! It works! But, what happens if someone doesn't care about what +your function and just decides to pass in something that's not a string? It +would make sense that reversing something that is not a string should lead to no +value, the absence of a value, because the input to the function doesn't make +sense. In that case, you can just return a `null` because there is _no value_ +that the function can return that would make sense. + +```js +function reverseTheSentence(sentence) { + if (typeof sentence !== 'string') { + return null; + } + let parts = sentence.split(' '); + parts.reverse(); + return parts.join(' '); +} +``` + +## An unknown value + +There are a lot of programmers that will argue that `null` cannot be an unknown +value. "The value is known!" they'll exclaim. "The value is 'null'! It's known! +It's 'null'! Stop saying it's not known!" + +There are programmers that vehemently disagree with that. + +![shrug](images/woman-shrugging_1f937-200d-2640-fe0f.png) + +## Checking if a value is null + +If you had hoped that you could use the `typeof` operator to check if a value is +`null`, then you're out of luck. + +```js +// Useless code. +console.log(typeof null); // 'object' +``` + +Silly JavaScript. Instead of using the `typeof` operator, you can just _compare_ +the value to `null` because there is only one value of the Null data type and +it's always `null`. Take a look at the following code and figure out what you +think it will produce. + +```js +let a = []; +let x = null; + +if (a === null) { + console.log('a is null'); +} else if (x === null) { + console.log('x is null'); +} +``` + +## Oh, and there's that undefined value, too + +Just like the `null` value that is the only value of the Null data type, there +is `undefined` which is the only value of the Undefined data type. + +If you're asking yourself, "Wait, if 'null' is no value or the absence of a +value, then what the heck does 'undefined' mean?", well you're not the only one. + +Have a look at this code. + +```js +let value; + +value = 6.28; +console.log(value); +``` + +You probably will not be surprised to see that it will print out "6.28" because +that's the value of `value`. But, what if you did this? What does that new +`console.log` print? + +```js +let value; +console.log(value); // <- what does this print? + +value = 6.28; +console.log(value); +``` + +If you guessed that it prints "undefined", you're right! When you declare a +variable, it's very first value is `undefined`. Most of the time, though, you'll +just immediately set it to a value. + +```js +let value = 6.28; +``` + +So, an uninitialized variable has the value `undefined` which is the only value +of the Undefined data type. To test for it, you can use the `typeof` operator +_or_ the strict equality operator. Using the strict equality operator is the +more common way to do that, now. + +```js +// Test if a value is undefined +if (value === undefined) { + // do a thing +} + +// You can also do it this way, but +// it is considered passé. +if (typeof value === 'undefined') { + // do a thing +} +``` + +## What happens when... + +Interestingly enough, all functions actually _do_ return values. Have a look at +this function. What value does it return? (Not a trick question.) + +```js +function returnsTrue() { + return true; +} +``` + +Yes, it returns the value `true`. But, what about this function? + +```js +function returnsWhat() { + return; +} +``` + +There's a `return` statement there but it does not specify a value. If there is +not value specified, what do you think this function returns? Try putting the +function definition above and the code below into a code runner and seeing what +happens. + +```js +console.log(returnsWhat()); +``` + +One you figure that out, try the same experiment but with this function. What +do you think it returns. It doesn't even have a `return` statement in it! + +```js +function whatIsThis() { +} +``` + +## What you've learned + +There is a special value in JavaScript represented as `null` which means "no +value" or "unknown value". It is the only value of the Null data type. You can +check that a value is `null` by using the strict equality operator `x === null`. + +The value `undefined` is used by JavaScript for variables that have not been +assigned a value. Also, functions that do not return an explicit value return +the value `undefined`. You can test if a value is `undefined` by using the +strict equality operator `x === undefined`. + +[reverse]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse +[split]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/split +[join]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join + +________________________________________________________________________________ +# Catch Me If You Can + +Sometimes bad things happen to good programs. Some person may enter some badly +formatted information. Another computer may try to attack your program by +sending it wonky data. A network could go down. A file can become corrupt. When +this happens, your running software will have some errors. This article is about +how you can recover from those errors with "structured exception handling". + +In this article you'll learn the answers to: + +* What _is_ structured exception handling? +* How can I do that in JavaScript? +* How can I make my own errors? +* What else can I do with it? +* Shouldn't I just always do this? + +## Structured exception handling + +Oddly enough, there are very few error-handling mechanisms in use, today, in all +programming languages. There are really only three ways that programming +language provide structured exception handling. + +* **Error or error code reporting** as found in languages like C and Go +* **Continuable exceptions** as found in Common Lisp +* **Stack unwinding** which is found in almost every modern programming + language including JavaScript and Python + +In the stack-unwinding paradigm, which is the one you'll use in JavaScript, when +an error occurs, the JavaScript interpreter (the thing running your JavaScript +code) looks for some kind of handler for that error. It has a very specific way +of searching for those handlers. The way JavaScript searches for the handlers is +very similar to the way it happens in Python, C++, Java, C#, and a lot of other +languages. Once you learn it, here, you will be able to handle errors when +writing code in all of those languages. + +## Try and catch + +Say you have some code that may have an error. For example: + +```js +function sumArray(array) { + let sum = 0; + for (let i = 0; i < array.length; i += 1) { + sum += array[i]; + } + return sum; +} +``` + +If someone calls the above function with the code `sumArray(null)`, then they +will get the error because the `for` loop is trying to get the `length` property +of the `array` parameter which is `null`. + +``` +TypeError: Cannot read property 'length' of null +``` + +To prevent this from ruining your program, you wrap code that may have an error +in a **try block**. Now, you've seen other blocks already: `if` blocks, `for` +blocks, `function` blocks. Basically, if there are curly braces around some +lines of code, that's a **code block** of some kind. A _try block_ is just some +curly braces with the `try` keyword. + +```js +// THIS IS AN INCOMPLETE BLOCK OF CODE +function sumArray(array) { + let sum = 0; + + // The try block wraps the for loop. If some + // error occurs, the try block will give you + // a chance to react to it so that the program + // doesn't terminate. + try { + for (let i = 0; i < array.length; i += 1) { + sum += array[i]; + } + } // needs something more here + + return sum; +} +``` + +The `try` block tells JavaScript that it needs to watch the code inside the +curly braces for an error. Now, you have to tell JavaScript what to do when +there _is_ an error. You do that in the `catch` block that should immediately +follow the `try` block. The `catch` block accepts a single parameter that +(usually) contains an object that describes the error that occurred. In the +case of the `sumArray` method, if an error occurs, you could return the value +`undefined` rather than letting an error terminate your program. You could also +log the error to the "error" output. + +```js +function sumArray(array) { + let sum = 0; + + try { + for (let i = 0; i < array.length; i += 1) { + sum += array[i]; + } + } catch (e) { + console.log(e); + return null; + } + + return sum; +} + +sumArray(null); +``` + +Just to state it, again: the _catch block_ runs when an error occurs in the _try +block_. If no error occurs in the _try block_, the _catch block_ **does not +run**. + +That `(e)` after the word `catch` is a variable that contains any error that was +thrown and caught by this `try-catch` block. It doesn't have to be named `e`. + +```js +function sumArray(array) { + let sum = 0; + + try { + for (let i = 0; i < array.length; i += 1) { + sum += array[i]; + } + } catch (pancakes) { + console.log(pancakes); + return null; + } + + return sum; +} + +sumArray(null); +``` + +Here is the same code but, instead of a variable named "e", there is a variable +named "pancakes". Now, if an error is thrown, the variable "pancakes" will +contain it. By long-standing tradition, the variables used with the catch block +are normally "e", "err", or "error". + +```js +// CODE SNIPPET, WILL NOT RUN +} catch (e) { +``` + +```js +// CODE SNIPPET, WILL NOT RUN +} catch (err) { +``` + +```js +// CODE SNIPPET, WILL NOT RUN +} catch (error) { +``` + +Now, when you run the code `sumArray(null)`, you should see something like the +following, if you run it in the online code editor. + +``` +TypeError: Cannot read property 'length' of null + at sumArray (/tmp/file.js:5:31) + at Object. (/tmp/file.js:16:1) + at Module._compile (internal/modules/cjs/loader.js:1158:30) + at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10) + at Module.load (internal/modules/cjs/loader.js:1002:32) + at Function.Module._load (internal/modules/cjs/loader.js:901:14) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) + at internal/main/run_main_module.js:18:47 +``` + +In that code sample, after the `sumArray(null)` call, the lines that begins +`TypeError` is the error that occurred. The next 10 lines are what is known as a +**stack trace**. You'll end up seeing these a lot, most likely, as you continue +your career in software programming. This is the first line in understanding +errors in your code. The _stack trace_ shows on the first line where the error +occurred: `sumArray (/tmp/file.js:5:31)` means that it occurred in the +`sumArray` method on line 5 of the content, at character 31. If you open up one +of the coding problems, paste that code block in, and run it, you'll see similar +output in the output block. + +The last line `undefined` is the return value of the `sumArray(null)` invocation +that now happens when an error occurs. + +That is how the so-called **try-catch block** works. + +## How can I make my own errors? + +To create your own errors with structured exception handling, you first need to +create an error object with the message that describes the error. Then, you need +to "throw" the error. That code would look like either of these two lines, the +only difference being the `new` keyword. They both work exactly the same. + +```js +throw Error('this happened because I wanted it to'); +throw new Error('this happened because I wanted it to'); +``` + +## What else is there? + +Turns out that you can have one more block on the _try-catch block_. It is the +**finally block**. The _finally block_ runs whether or not an error occurs. It +_always_ runs. + +```js +function sumArray(array) { + let sum = 0; + + try { + for (let i = 0; i < array.length; i += 1) { + sum += array[i]; + } + } catch (e) { + console.log(e); + return null; + } finally { + console.log('you will always see this.'); + } + + return sum; +} +``` + +## How do I best use this? + +At this point, you may be asking yourself, "Self, since errors can occur +everywhere, shouldn't I just wrap _all_ of my code in these _try-catch blocks_?" + +No. No, you shouldn't. + +Every **try-catch block** introduces another slow-down in your code. If you're +writing code that you want to run as fast as possible, then you write as few +_try-catch blocks_ as possible. Also, it makes the code pretty cluttered with +all of the indentation and curly braces. When at all possible, you should write +**defensive code** which checks for bad values before errors get thrown in your +code. Rather than using a _try-catch block_ in the `sumArray` function, you +could defend against bad values of the `array` parameter like so. + +```js +function sumArray(array) { + if (array === null) { + return null; + } + + let sum = 0; + for (let i = 0; i < array.length; i += 1) { + sum += array[i]; + } + return sum; +} +``` + +## Review + +The _try-catch-finally block_ is a mechanism to handle errors in your code. You +should _not_ wrap all of your code in these blocks because it can seriously +degrade the performance of your application. Instead, only wrap those portions +of the code that you want to guard against throwing exceptions. + +A better choice, in JavaScript and all programming languages, is to be +defensive about your programming and choose to check that the value that you +have has the functionality that you desire by adding code like + +```js +if (value !== undefined) {} +if (value !== null) {} +```