First we have to understand some common sense, important first!! It’s also a prerequisite for learning about closures!

Basic knowledge of

Scope: A scope is the area of a program’s source code where variables are defined. Scope purpose: A scope specifies the rules for how and where to look for variables. That is, it determines how the currently executing code has access to variables.

A variable's scope is the area in the program's source code where it is defined. Global variables have global scope and are defined anywhere in the JavaScript code. Variables declared inside a function are defined only inside the function body. They are local variables and their scope is local. Function parameters are also local variables that are defined only within the body of the function.Copy the code

Common sense:

ECMAScript6 has only global and function scopes before, and block-level scopes after let const

Lexical scopes also become static scopes when the scope is defined at code writing time.

JavaScript is a lexical scoped language.

Okay, so these are the things we need to know, and we’re going to cover each of them.

scope

The simplest explanation is this: a scope specifies the rules for how and where to look for variables, which determines access to the currently executing code

Variable scope

The scope of a variable is the area in the program source code that defines the variable.

There is also a distinction between global and local variables

Variables declared globally have global scope and are defined anywhere in the JavaScript code. Variables declared inside a function are defined only inside the function body. They are local variables and their scope is local. Function parameters are also local variables that are defined only within the body of the function. JavaScript is a lexical scoped language: the scope of a variable can be known by reading the source code that contains the variable definition, which means that the scope of the variable is defined at the time it is written

Pay attention to the point

In the function body, local variables have high priority over global variables of the same name.

var name = 'zyc';
var firstname = 'z';
function showName(){
  console.log('zyc')
}
function test(func){
  var name = 'dalao';
  firstname = 'da'
  func = function(){
    console.log('dalao')
  }
  func() // dalao
}
test(showName);
showName() // zyc
name // zyc
firstname // da
Copy the code

You can see that our global variables are being modified in the function, which is not what we want, so declare variables in the function using var to avoid overwriting global variables. If it does not exist, a global variable is implicitly generated, which can be eliminated by turning on strict mode.

function test(){
  name = 'zyc'
  var tom = 'Tom'
}
test()
console.log(name) // zyc
console.log(tom) // ReferenceError tom is not defined
Copy the code

Our Tom in the global environment access function scope is not accessible

function test(){
  name = 'zyc'
}
console.log(name) // ReferenceError name is not defined
Copy the code
'use strict';
function test(){
  name = 'zyc'
}
test()
console.log(name) // ReferenceError name is not defined
Copy the code
function test(){
  'use strict';
  name = 'zyc'
}
test()
console.log(name) // ReferenceError name is not defined
Copy the code

Variable ascension

Function declarations and variable declarations are always implicitly promoted by the JavaScript interpreter to the top of the scope that contains them. Obviously, the language definition and function parameters are already at the top of the scope and assigned to undefined.

Function scope

ECMAScript6 previously had only global and function scopes

Function scope: Variables are defined in the body of the function in which they are declared and in any nested function.

Nested functions of a function body can access variables of the parent function body. This relationship is inheritable, and child nested functions can access variables in the parent function body.

function test(){
  function foo(){
    var tom = 'Tom'
    console.log(tom) // Tom
  }
  foo()
  console.log(tom) // ReferenceError Tom is not defined
}
test()
Copy the code
var name = 'zyc'; // Global variablesfunction foo() {// console.log(name); } foo(); // zycfunction bar() { var name = 2; foo(); } bar();Copy the code

Examples from the Authoritative guide:

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f(); // Execute here
}
checkscope(); // local scope
Copy the code
var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}
checkscope()(); // Execute here
// local scope
Copy the code

Both pieces of code print ‘local scope’.

JavaScript functions are executed using the scope chain, which is created when the function is defined. The nested function f() is defined in the scope chain, where the variable scope must be a local variable. This binding remains in effect when f() is executed, no matter where or when f() is executed.

What’s the difference between the two pieces of code?

Lexical scope

Lexical scope is also called static scope

JavaScript is a lexical scoped language: the scope of a variable can be known by reading the source code that contains the variable definition, which means that the scope of the variable is defined at the time it is written

Global variables are always defined in a program. A local variable is always defined in the body of the function that declares it and in the nested function.

The scope chain

It’s an abstract concept.

If a local variable is treated as a property of a custom implemented object, then each piece of code has a scope chain associated with it.

The scope chain can be thought of as a list or linked list of objects that define the variables in the scope of the code.

When JavaScript needs to find the value of a variable, it starts with the first object in the chain, uses the value if there is one, moves on to the next object if there is none, and throws a ReferenceError if there is none.

In the top-level code of JavaScript (code not included in any function definition), a scope chain is made up of a global object.

In the body of a function that does not contain nesting, there are two objects on the scope chain, the first is the object that defines function parameters and local variables, and the second is the global object. Contains nested function bodies with at least three objects in the scope chain.

Block-level scope

What is block-level scope? How does ECMAScript6 introduce block-level scopes? What kind of?

I believe that these questions are looking at block level scope confusion.

Block-level scope: In some C-like programming languages, each piece of code inside {has its own scope, and variables are not visible outside the code block in which they are declared.

Block-level manipulation is very strict, meaning that variables outside the scope cannot be accessed within the scope.

ECMAScript5 specifies let and const to support block-level scoping (with the same effect).

In addition, the scope for if switch will not be generated before ECMAScript5. After ECMAScript6, there are some differences, so I need to check some information.

The title

What will be printed next?

var a = 5;
function todo(){
    var a = 9
    return function(){
        a = 7
    }
}
todo()()
console.log(a)
Copy the code