Skip to content

Latest commit

 

History

History
227 lines (177 loc) · 7.78 KB

File metadata and controls

227 lines (177 loc) · 7.78 KB

15. Scope

[toc]


15.1. Introduction

Back in Chapter 10, we saw that where variables are declared and initialized in the code affects where they can be used. This idea is called scope, and it is used to describe the ability of a program to acces or modify a variable.

Example:

let a = 0;						// a is "global"

function coolFunction() {
   let b = 2;					// b is "local"
   return a + b;
}

a is accessible inside and outside of coolFunction. It has global scope.

b is only accessible inside of coolFunction. It has local scope.

Let's add some console.log statements to explore this code snippet.

Example:

let a = 0;
console.log(a);

function coolFunction() {
   let b = 2;
   console.log(`a = ${a}, b = ${b}.`);
   return a + b;
}

a += 1;
console.log(a);

coolFunction();
console.log(b);
0
1
a = 1, b = 2.
ReferenceError: b is not defined
  1. Lines 2 and 11 print the intial an incremented values of a.
  2. Line 13 calls coolFunction(), and line 6 prints the values of a and b. This shows that both variables are accessible within the function.
  3. Line 14 throws a ReferenceError, showing that b is not accessbile outside of coolFunction.

15.1.1. Block/Local Scope

==Local scope refers to variables declared and intialized inside a function or (code) block. A locally scoped variable can only be referenced inside of the block or function where it is defined.== In the example above, b has a local scope limited to coolFunction(). ==Referencing or attempting to update b outside of the function leads to a scoping error.==

🧩Try It! The following code has an error related to scope. Try to fix it! (Link)

function myFunction() {
   let i = 10;
   return 10 + i;
}

console.log(i);

15.1.2. Global Scope

==Global scope refers to variables declared and initialized outside of a function and in the main body of the file. These variables are accessible to any function witin a file.== In the first example above, a has global scope.

Global scope is the default in JavaScript. If you assign a value to a variable WITHOUT declaring it with let or const, then the variable automatically becomes global.

Example:

// Code here CAN use newVariable.

function coolFunction() {
   newVariable = 5;
   return newVariable;
}

// Code here CAN use newVariable.

⚠️ WARNING! In a for loop, for(i = 0; i < string.lenght; i++) leaving out the let from i = 0 means that i is treated as a global variable. ANY other portion of the program can access or modify i, which could disrupt how well the lopp operates.

15.1.3. Execution Context

Execution context refers to the conditions underwhich a variable is executed--its scope. Scoping affects the variable's behavior at runtime.. When the code is run in the browser, everything is run at a global context. As the complier processes the code and finds a function, it shifts into the function context before returning to global execution context.

Let's look at this code.

let a = 0;

function coolFunction() {
   let b = 2;
   return a + b;
}

function coolerFunction() {
   let c = 5;
   c += coolFunction();
   return c;
}

console.log(coolFunction());
console.log(coolerFunction());

Now, let's consider the global execution context (GEC) for each step.

🎗️ TODO: Insert some state diagrams or flow charts later.

  1. First, the GEC is entered as the compiler executes the code.
  2. Once coolFunction() is hit, the compiler creates and executes coolFunction() under the coolFunction() execution context.
  3. Upon completion, the compiler returns to the GEC.
  4. The compiler stays at the GEC until the creation and execution of coolerFunction().
  5. Inside of coolerFunction() is a call to coolFunction(). The compiler will go up in the execution context to coolFunction() before returning down to coolerFunction()'s execution context. Upon completion of that function, the compiler returns to the GEC.

🎗️ TODO: Here would be a good time to introduce currying later.

15.1.4. Check Your Understanding ✅

Both of the concept checks refere to the following code block:

function myFunction(n) {
   let a = 100;
   return a + n;
}

let x = 0;

x = myFunction(x);

Question: What scope is variable x? a. Global b. Local

Answer: a. (x is global.)

Question: In what order with the compiler execute the code? :exclamation: Answer:

15.2. Using Scope

==Scope allows programers to control the flow of information trhough variables in their programs.== Some variables you want to set up as constants (like $\pi$), which can be accessed globally. Others you want to keep secure to minimize the danger of accidental updates, like a variable holding someone's user name which should be kept secure.

15.2.1. Shadowing

==Variable shadowing is where two variables in different scopes have the same name. The variables can be accessed under different context. However, shadowing can affect the variable's accessibility. It can also cause confusion for anyone reviewing the code.==

Example

const input = require('readline-sync');

function hello(name) {				// @param name
   console.log('Hello,', name);		// @param name
   name = 'Ruth';					// @param name
   return doubleName(name);			// @param name
}

function doubleName(name){			// @param name
   console.log(name+name);			// @param name x2
   return name+name;				// @param name x2
}

let name = input.question("Please enter your name: ");	// global name

hello(name);		// global name
doubleName(name);	// global name
console.log(name);	// global name

So what's the value of the name in lines 4, 10, 16, 17, and 18? If you are curious, why not 🧩try it! (Link)

==This example is a good reason why shadowing is NOT a best practice in coding.== For your conveinence, I added some comments to show which variable was being used. This likely won't be the case when you look at code else where. ==Whenever possible, use different global and local names.==

15.2.2. Variable Hoisting

==Variable hoisting is a behavior in JavaScript where variable declarations are raised to the top of the current scope. This results in a program being able to use a variable before it has been declared. Hoisting occurs when the var keyword is used in the declaration, but it does NOT occur when let and const are used in the declaration.==

ℹ️ NOTE: Although we do not use the var keyword in this course, you will see it used in a lot of other JavaScript resoruces. Variable hoisting is an important concept to keep in mid as you work with JavaScript.

15.2.3. Check Your Understaind ✅

Question: What keywords allow a variable to be hoisted?

a. let b. var c. const

Answer: b. ==var allows hoisting to occur, let and const do not.==

Question: Consider this code:

let a = 0;

function myFunction() {
   let a = 10;
   return a;
}

Because there are two separate variables with the name a under two different scopes, a is being shadowed. a. True b. False

Answer: a. TRUE. a was declared inside of myFunction, but the inner a will be used.

🏁 Wasn't that good to have a nice short chapter. Chapter 16 is going to be even better.


#LaunchCode