“This is the first day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021”

Function scope and block scope

A scope in a function

Consider the following code:

function foo(a){
    var b = 2;
    // Some code
    function bar(){
        // ...
    }
    // More code
    var c = 3;
}
Copy the code

Since identifiers A, B, C, and bar are all attached to foo(…) , so neither can be retrieved from foo(…). External access to them

bar();/ / fail
console.log(a,b,c);// All fail
Copy the code

The meaning of a function scope is that all variables belonging to the function can be used and reused throughout the scope of the function (in fact, nested scopes can also be used). Take advantage of the “dynamic” nature of JavaScript variables that can change value types as needed

Hide the internal implementation

Minimum authorization or minimum exposure principle: The principle that in software design, the minimum necessary content should be exposed and everything else should be “hidden”, such as the API design of a module or object

function doSomething(a) {
   b = a + doSomethingElse(a * 2);
   console.log(b * 3);
}

function doSomethingElse(a) {
   return a - 1;
}

var b;
doSomething(2);/ / 15
Copy the code

Internal privatization

function doSomething(a) {
   function doSomethingElse(a) {
      return a - 1;
   }
   var b;
   b = a + doSomethingElse(a * 2);
   console.log(b * 3);
}
doSomething(2);/ / 15
Copy the code

Function scope

The easiest way to distinguish a function declaration from an expression is to look at where the function keyword appears in the declaration (not just in one line of code, but in the entire declaration). If function is the first word in the declaration, it is a function declaration; otherwise, it is a function expression. The most important difference is where their name identifiers will be bound.

Anonymous and named

Function expressions can be anonymous while function declarations cannot omit function names

  • Anonymous functions do not show meaningful function names in the stack trace, making debugging difficult (Inconvenient debugging)
  • Without a function name, the expired arguments.callee reference can only be used when the function needs to reference itself, such as in recursion. Another example of a function needing to reference itself is when the event listener needs to unbind itself after the event is fired. (The complexity of referencing itself)
  • Anonymous functions omit function names that are important to code readability/understandability. A descriptive name lets the code speak for itself. (Reduced code readability)

Inline function expressions are powerful and useful, and it is a best practice to always name function expressions

Execute function expressions now (IIFE)

Three usages:

  • Call them as functions and pass them in

var a = 2;
(function IIFE(global) {
   var a = 3;
   console.log(a);/ / 3
   console.log(global.a);/ / 2}) (window)
console.log(a);/ / 2
Copy the code
  • Resolve an exception caused by an error overwriting the default value of undefined identifier (although not common)
undefined = true;// Never do this
(function IIFE(undefined) {
  var a;
  if (a === undefined) {
    console.log("Undefined is safe here");
  }
})();
Copy the code
  • Another variation of IIFE is to invert the running order of the code, placing the function to be run in the second place and passing it in as an argument after IIFE execution
(function IIFE(def) {
  def(window); }) (function def(global) {
  var a = 3;
  console.log(a);/ / 3
  console.log(global.a);/ / 2
})
Copy the code

Block scope

Block scope is a tool used to extend the previous principle of minimum authorization by extending code from hiding information in functions to hiding information in blocks.

1. With is a form of block scope. Scopes created from objects with with are valid only in the with declaration, not in the outer scope.

The catch clause of the try/catch clause creates a block scope in which variables declared are valid only inside the catch

try {
  undefined(a);// Perform an illegal operation to force an exception
} catch (err) {
  console.log(err);// Can be executed normally
}
console.log(err);//err not found
Copy the code

Err exists only inside the catch clause, and an error is thrown when an attempt is made to reference it from elsewhere

The let let keyword binds variables to any scope they are in (usually {.. } inside), let implicitly defines the block scope for the variables it declares.

4. Const can also be used to create a scope variable, but its value is fixed (constant)