Home  >  Article  >  Web Front-end  >  Detailed introduction to scope in JavaScript (code example)

Detailed introduction to scope in JavaScript (code example)

不言
不言forward
2019-03-11 16:59:121686browse

This article brings you a detailed introduction (code example) about scope in JavaScript. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you. helped.

Almost all programming languages ​​have the concept of scope. So what exactly does scope refer to? Scope is a set of rules for how variables are stored and accessed when a programming language defines variables. The rules of different programming languages ​​are similar. Next, let’s take a look at how this set of rules is set.

Compilation principle

In traditional compiled languages, there will be a compilation process before the code is executed:

  • Word segmentation/lexical analysis: decompose the code statement into Meaningful code blocks, also called lexical units.
  • Parsing/grammatical analysis: Convert lexical units into a tree structure with grammatical rules nested level by level, also called abstract syntax tree (AST)
  • Code generation: parse AST and convert The machine instructions

are different from traditional compiled languages. The compilation and execution of js are not executed separately. In most cases, they will be executed immediately after the compilation process is completed. In order to shorten the compilation process in a short time Achieve optimal performance within the time limit. The js engine is more complex than the general compiler. Now let’s take a look at the js compilation process. Simply take the compilation of var a = 2 as an example:

  • When encountering var a, The compiler will ask the scope if a variable with that name already exists in the collection of the same scope. If so, the compiler will ignore the declaration and continue compilation; otherwise it will ask the scope to declare a new variable a
  • in the collection of the current scope. Next, the compiler will generate the runtime requirements for the engine. The codes are used to handle the assignment operation of a=2. When the engine is running, it will first ask the scope whether there is a variable called a in the current scope set. If not, the engine will use this variable; if the engine finally finds a, it will assign 2 to it. Otherwise the engine will throw an exception

Lexical Scope

Scope generally has two working models, the first one is used by most programming languages The other type of lexical scope used is called dynamic scope. For example, Bash script uses dynamic scope. Lexical scope is the scope defined in the lexical stage. Lexical scope is determined by where you write variables and block scopes when you write code. It is determined by the location of variable definition, while dynamic scope is determined by the use of variables. determined by the location. Let’s take a look at an example:

function foo(a) {
  var b = a * 2;
  function bar(c) {
    console.log(a, b, c)
  }
  bar(b * 3)
}
foo(2)

First, let’s analyze how many scopes there are in total?

  1. Global scope, which contains the foo variable
  2. The scope created by the foo function, which contains the a, b, bar variables
  3. The scope created by the bar function , there are c variables in it

Next, let’s analyze the variable search process. When the engine executes console.log(), it needs to find references to the three variables a, b, and c. First, start from the innermost bar () scope, the engine cannot find a, so it will search up to the foo() scope. It finds a here and stops searching. The search process is the same for b and c. Scope search always starts from the innermost level of the runtime and searches outwards until the first matching variable is encountered.

Function scope

Function scope means that all variables belonging to this function can be used and reused within the scope of the entire function. This is what everyone knows We know the definition, but what is the use of the existence of function scope? Next, let’s take a look at the seconds of function scope.

Hide internal implementation

Hiding internal implementation is to wrap variables and functions in the scope of a function to achieve the purpose of hiding. Why do you do this? There is a very famous principle in software design called the principle of minimal exposure, which refers to exposing the necessary content to the minimum and hiding other content, such as the API design of modules or objects. Use function scope to wrap variables and functions to achieve the principle of minimal exposure and prevent direct external access. Take a look at the following example:

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

In this code, doSomethingElse and b should be private within doSomething, but they are not. Being exposed, this will lead to being used in unexpected forms and produce unexpected results. A more reasonable design should be to hide these private contents inside doSomething, for example:

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

This way b Neither doSomethingElse nor doSomethingElse can be accessed from outside doSomething, but there will also be some problems. First, the doSomething function is declared in the global scope, polluting the global role. Secondly, it must be executed through explicit calls. So is there any way to avoid this? Can the polluted scope be self-executed without calling it? The answer is a function expression, look at the following example:

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

First look at (function doSomething(){}) which is a function expression. Different from the function declaration, it is enclosed in parentheses, and then (function doSomething(a){})() calls by value, so that it can be self-executed and will not pollute the scope. The community has defined a term for this usage: IIFE, which stands for immediate execution of function expression

块作用域

除JavaScript外很多编程语言都支持块作用域,尽管你可能写过很伪块作用域形式的代码,最常见的就是for循环:

for(var i=0; i<10; i++) {
  console.log(i)
}

写这段代码通常是希望变量i在循环内部使用,但是实际上i会被绑定到外部作用域中,要确保没有在作用域的其他地方意外使用i,就只能依靠自觉,这时候块级作用域就显得尤为有用,ES6改变了现状,引入了新的let、const关键字,let关键字可以将变量绑定到所在的任意作用域中,也就是let为其声明的变量隐式地创建了作用域:

for(let i=0; i<10; i++) {
  console.log(i)        
}
console.log(i) // ReferenceError

这时候i就只会在for循环的内部有效


The above is the detailed content of Detailed introduction to scope in JavaScript (code example). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete