This is the 22nd day of my participation in the August More Text Challenge

JS scope is a set of variable search rules, used to determine how to find variables in the code execution can be accessed within the scope, any language has the concept of scope, in the JS world, scope is divided into global scope, function scope and block level scope

Global scope: Objects in a global scope can be accessed anywhere in the code, and their life cycle follows the life of the page.

Function scope: a variable or function defined inside a function that can only be accessed inside the function. After the function is executed, the variables defined inside the function are destroyed.

Block-level scope: A piece of code wrapped in braces, such as a function, a judgment statement, a loop statement, or even a single {}, can be considered a block-level scope.

Function scope

A variable defined in a function is called a function variable, and it can only be accessed from inside the function, so its scope is called the function scope

const getName = () = > {
  var name = 'nordon';
  console.log(name)
}

const fn = () = > {
  console.log(name)
}

getName();
fn();
Copy the code

The variable name is defined in the getName function, which exists as a variable in the function scope. When the function getName is executed, the value of name can be obtained

When function fn is executed, its corresponding function scope does not define the name variable. It is searched along the scope chain and returns undefined

Global scope

Variables defined in the global context are hung under the Window object by default and can be accessed anywhere in the code

var name = 'nordon';

const fn = () = > {
  console.log(name) / / equivalent window. The name
}

fn();
Copy the code

When the function fn is executed, it will look in the function scope of fn. If it is not found, it will look in the global scope. If it is not found, it will return undefined

Block-level scope

ES6 adds block-level scoping for let and const declared variables, making JavaScript more scoped. Block-level scopes, as the name suggests, are limited to code blocks and have a temporary dead zone, meaning that the variable cannot be used until it is defined.

const fn = () = > {
  console.log(name)
  var name = 'norodn'
}

fn()
Copy the code

Before ES6, the variable was promoted and the output was: undefined because the variable name was promoted inside the function. Is equivalent to:

const fn = () = > {
  var name = undefined
  console.log(name)
  name = 'norodn'
}

fn()
Copy the code

Declaring a variable with a let or const creates a closed block-level scope for that variable, in which referenceError is reported if the variable is accessed before it is declared

const fn = () = > {
  console.log(name)
  let name = 'norodn'
}

fn()
Copy the code

Uncaught ReferenceError: Cannot access ‘name’ before Initialization

If accessed after the variable has been declared, the value of the variable can be retrieved normally

const fn = () = > {
  let name = 'norodn'
  console.log(name)
}

fn()
Copy the code

So what is block-level scope

Any variable defined within a pair of curly braces {} will generate a separate scope

const fn = () = > {
  console.log(name) // Uncaught ReferenceError: name is not defined
  if(true) {
    let name = '1'
  }
}

fn()
Copy the code

The name variable is only used in block-level scoped if judgments and is not available elsewhere in the domain function scope fn

A classic interview question about block-level scopes:


function fn(){
  for(var i = 1; i <= 10; i ++){
    setTimeout(function() {
      console.log(i)
    }, 0)
  }
}

fn()
Copy the code

Because there is variable I in function scope fn, when the timer is executed, variable I in function scope will be put. At this time, I in function scope is already 11, so the console will output 10 11s at this time

If you want to print 1,2,3… Var can be changed to let to make it block-level scope. Then every time the timer executes a callback function, it will be looked up in the block-level scope it executes

for(let i = 1; i <= 10; i ++){ // var to let
}
Copy the code