Handling Data
Understanding Scope
What is SCOPE? Scope is the context, or region of code, in which a variable exits and can be accessed. JavaScript has a lexical scope – scope of a variable depends where it was declared.
We have two types of scope: global and local
Local Scope
Local scope includes block scope and function scope.
Block Scope
Variables declared using let and const possess block scope. They are only accessible within the code block in which they were declared, as well as any child blocks.
Code block: Any set of statements executed as part of a function definition, if or switch statement, while or do… while loop, etc… Basically any statements typically contained within curly braces can be considered a code block.
Lets look at this example in a console:
We get an error saying that the variable is not defined. Note: Not defined is not the same as undefined. Undefined is a valid JavaScript datatype that says that a variable was declared but its value has not be initialized. Not defined means that the variable was not declared at all, which is what we are seeing in the error above, because we try to access it from outside of the block within which it was declared. When that if block ended the variable test far was deleted and does not exist any more. Scope is inherited from the parent block to the child block, however, so if I had something like this in the example below. The inner child if block is able to access the value of testVar that was set outside of it, because it was declared in its parent block.
The opposite would not work if I declare a variable in the child block, the parent block cannot see it. See the the example below:
It’s possible to declare variables with the same name in different code blocks, for example below:
Typically though you’re going to want to avoid reusing variable names close to each other like this as that can get confusing.
Global Scope
Variables declared outside of any code block have global scope: They are available everywhere inside any code block of that program. That should make some sense from our talk on how inner child blocks inherit variables scoped in the outer parent block. Think of the global scope as the parent block for all the code in your program.
Best practice: Declare variables where they will be used with local scope. Avoid using global scope as much as possible for most variables lead to confusion and bugs from globals being modified. Hard-coded constants that will not be assigned dynamically, and will be used in multiple places within the code, are often set as globals.
Function Scope
Local scope – similar to block scope but only applies to function blocks. Function scope is another type of local scope. It’s similar to block scope but it only applies to function blocks. It does not apply to any other kind blocks, such as: if blocks, switch blocks, etc.
Block scope is used by variables declared using let and const keywords.
Function scope is be variables declared with pre-ES6 var keyword.
If we declare a variable using var inside a if block , it is available outside of the if block. See this example below:
If we declare it inside a function block. It is not available outside of the function block. See example below here:
The block scope for let and const variables is considered to be an improvement over function scope and that is one of the reasons that let and const are now recommended for use over var.
Arrays
What are Arrays? Arrays are numerically indexed collections of values. Arrays can contain strings, numbers, Booleans, even other arrays. Each item in an array is associated with a number based on its order of appearance in the array, starting with 0.
Creating an Array
To create an array, use the array literal syntax, using square brackets: [item1, item2, item3,…]
If you want to use an array more than once, store the array literal in a variable, ex: const groceryList = [‘eggs’, ‘coffee beans’, ‘salad’]; This grocery list contains three strings. This array contains a list of lucky numbers: let luckyNumbers = [7, 23, 99, 11, 777]
It is permitted for an array to contain values of a mixed data type like this: let anArray = [7, ‘eggs’, 99, ‘salad’, true];
Accessing Array Items
Once you have created an array and assigned it to a variable. How do you access the items inside it? Arrays are numerically indexed, specifically they are zero indexed. Arrays are zero-indexed: an array’s index starts with 0. Look at the example below:
Remember!!! Arrays start with 0 not 1!! You can use the index of the array to access the items stored at a particular position using what’s called bracket notation. Here are some examples. You use the variable name of the array followed immediately by a set of square brackets with the index number inside it.
Modifying Array Items
To modify array items, use the index with bracket notation & assignment operator. Say in the example below, what if we want to replace eggs with bananas and salad with soap. So if we know the index for both items we can replace them like this:
Array Property: Length
All arrays have a length property: a count of the total number of items inside the array – arrayName.length
This is the count of items, which starts at 1 – different from the array index, which starts at 0!
Though the length of this array above is 3, the index is 0 through 2.
We can use the length property to figure out the index, by the last item in an array by subtracting 1 from the length to account for that difference. In this example below we accessing the last item in the grocery lists array by picking its length of 3 and subtracting 1 to get 2. Then we are using that inside the brackets to access the last item in the array. If we did not subtract 1 here we would get back undefined instead of soap because there’s no item at index 3 in the array.
Array Methods
All arrays can access a large number of built-in JavaScript array functions, called array methods: arrayName.methodName(argumentlist)
Some array methods have parameters, some don’t. Most array methods return a value of some kind.
Some array methods are mutators – they mutate the array; others are not, and it’s important to know which are which.
Array Methods: POP() and PUSH()
POP and PUSH are both mutator methods, and they both return a value.
The return value from pop() is the item that was removed.
The return value from push() is the new length of the array.
Array Methods: Shift() and Unshift()
SHIFT and UNSHIFT are both mutator methods, and they both return a value.
The return value from shift() is the item that was removed.
The return value from unshift() is the new length of the array..
Now unlike POP and PUSH, Shift() and unshift() change the index of all other items in the array.
Array Methods: JOIN()
join() takes all items in an array and returns a single string containing those items.
It takes an optional string argument that will be used as the separator – if no argument is provided, a comma is used as the default separator.
The join() method does not mutate the original array.
Array Methods: Includes()
includes() is used to check if an item exists inside an array. It will return a Boolean value of true or false.
includes() method does mutate the original array.
Array Methods: INDEXOF()
indexOf() also checks if an item is in array, but instead of true or false, it return the index of the item if it exists in the array.
indexOf() is also a non-mutating array method.
Generating Random Numbers
The Math Global Object
Math is a built-in global object in JavaScript that we can use to access certain math-related functions. which are called methods of the Math global object.
We will use two of these to help us generate random numbers: Math.random() and Math.floor()
MATH.RANDOM()
Math.random() generates a random number between 0 and 1. It does not take an argument. You can store this number inside a variable like so, it might generate a number like these:
The potential value of this number includes 0 but not 1.
To generate a number between 0 and a number higher than 1, multiply the random number. For example to generate a number between 0-6, but not including 6:
The highest possible value for this random number would be 5.999999999… but never reaching 6!
But what if you wanted a number without decimals! You would use MATH.FLOOR()
Math.floor() removes all digits to the right of the decimal point from a number. You pass it the number you want to “floor” as an argument:
const anInteger = Math.floor(3.14); —- It would return anIntger 3
So you can use Math.floor() and Math.random() together like this:
const randomInteger = Math.floor(Math.random() * 6); //Would create one of these numbers 0,1,2,3,4,5 but not 6!
If you want a random number between 1-6 rather rather than 0-5, add 1 to result:
const randomInteger = Math.floor(Math.random() * 6) +1;