# Scope ## What is scope? Definition from [Dictionary.com](http://www.dictionary.com/browse/scope): > noun 1\. extent or range of view, outlook, application, operation, effectiveness, etc.: If you imagine yourself as the computer that is executing your JavaScript code, you can think of scope as meaning: > what you can see from where you are In this case the 'things' that you are looking for are variables and functions. When we say, "What's in scope?", we mean "Which variables and functions can be accessed from the current point of execution in your code?" As it happens, in JavaScript there are three types of scope to consider. ## Global scope Variables and functions defined at global scope are visible from any point of execution in your code. Sometimes that's a good thing (or even essential), but in general you must avoid creating variables and functions in global scope unless you have specific reasons to do so. Consider the example below: ```js a = 'Hello'; // don't do this console.log(a); ``` In this example we have assigned the value `'Hello'` to a variable that we forgot to declare (we forgot to use `let`, `const` or `var`). The JavaScript engine tries to be helpful and defines a variable `a` for us in **global** scope. More recently, the JavaScript community considered this friendliness to be a mistake and with ES5 introduced `strict` mode: place the string `'use strict';` at the top of your file. This now causes our code to fail with a run-time error when forgetting to 'declare' our variables. ```js 'use strict'; a = 'Hello'; // produces: ReferenceError: a is not defined console.log(a); ``` You can correct this by declaring your variable with `let`, `const` or `var`: ```js 'use strict'; var a = 'Hello'; console.log(a); ``` This still puts the variable `a` into the global scope. So why is global scope a problem? Because you cannot be sure that the variable names you choose do not conflict with names already present in global scope (global scope is a busy place). It is best to apply the principle of 'need to know'. Only expose your variables to other parts in the JavaScript ecosystem that need to know about them. This is where local scope and block scope come in. ## Local scope When you declare a function in JavaScript the function body represents a new, local scope, distinct from global scope. Variables defined in the function body are visible in that function body only: from the outside, you can't look in. ```js 'use strict'; function myFunction() { const a = 'Hello'; console.log(a); } myFunction(); // console.log(a); <= this would produce: ReferenceError: a is not defined ``` But from the inside you can look out. In the example below the variable `a` is visible from inside the function body. ```js 'use strict'; const a = 'Hello'; function myFunction() { const b = ', world'; console.log(a + b); } myFunction(); ``` You might think that the variable `a` is in global scope. Actually, variables declared with either `let` or `const` have block scope, as will be discussed next. Note however that the function `myFunction` still resides in global scope. There is a way to get `myFunction` out of the global scope by using, what is called, an **IIFE** to create a **local scope** (or, with ES6, by placing the function definition in a block to create a **block scope**). See further down below. ## Block scope The keywords `let` and `const` were introduced in ES6 as alternatives to the existing `var` keyword. We recommend that you use these newer keywords instead of `var`. They adhere to the rules for **block scope**, whereas `var` is completely oblivious of the concept. A new block scope (sometimes called _lexical_ scope) is created whenever you create a block of code inside a pair of curly braces. (Exception: the curly braces used to enclose the body of a function definition do not create a block scope. Instead, a **local scope** is created as discussed in the previous section.) Variables defined with `let` and `const` at the file level (i.e., not inside a function or a block) are considered to be in a file-level block scope ('script' scope). That's why the variable `a` in the previous code snippet is not in global scope. Had we replaced `const a` with `var a` then variable `a` _would be_ in global scope. ## Scope Example In the figure below we show an example bringing all scope types together. The code fragment on the right-hand side is executed by means of a `