Front-end interviewer: Talk about scope in JavaScript, won't you? Next

Preface

Learning any programming language requires cognition of scope. Because the scope will affect the definition and life cycle of the identifier. I don’t feel convincing, it’s too pale to say much, let’s study together~

The role of scope in programming

I regard the scope as an'object', this object has its own temper (ps: temper is the rule) but we can't access the object in a coded way. It exists inside the JavaScript engine and is used to manage it according to the rules. How the engine works in the current scope. A deep understanding of the scope allows us to better identify the valid range of identifiers and the search for identifiers during the encoding process.

Classification of scope

In the language of JavaScript, lexical scope is used; that is, where you write variables and block-level scopes when you write code. (Ps: can be understood as static scope).

The opposite of static scope is dynamic scope. Of course, JavaScript also has some special cases that use dynamic scope. Such as eval(...) and with. (ps: Considering performance issues, it is generally not recommended).

When we define variables in coding, we have already determined the scope of these variables. How to analyze the effective scope of these variables, we must first understand the classification of JavaScript scope. JavaScript scopes are:

  • Global scope
  • Function scope
  • Block scope

Global scope

The global scope can be understood as the effective scope of the variable can be accessed at any location in the code.

  • Window is a global object, so the properties of the window object have global scope

    Then the functions declared by function in the outermost layer of the code, variables declared by var outside the outermost function, and direct LHS query assignment operations without keyword declaration will all be mounted on the window object. As shown in the following code:

 function foo(){
    innerValueB=4	//会先在window对象上创建一个innerValueB属性再赋值
    console.log('foo')
}
    foo();
    var outValueB=3;
    console.log('window:',this,this.foo,this.outValueB,this.innerValueB)  
  • In the outermost layer of the function through let and const declaration

    Variables declared by let or constants declared by const are not bound to the window object, but if you declare at the outermost level of the function, they also belong to the global scope.

let a=3;
console.log(this.a,this)	//undefined window

To define and declare variables in the way described above, they are all global variables. Will not be recycled by the browser engine (ps: unless manually set to null). Then with the increase of global variables in the project, it will not only cause conflicts of variable names, but also may cause memory leaks.

Visible: Global variables should be used as little as possible in the coding process.

Function scope

Function scope is the variable declared inside the function (ps: can be called local variable), then the effective scope of the variable is generally accessible inside the function. Of course there are special cases (except for ps: closures).

The function scope is automatically generated by function declarations and function expressions, for example:

function foo1(){...}			//通过function声明 foo1
(function foo2(){...})();	//立即执行函数 foo2

Function foo1 is declared in the global scope, so foo1 can be accessed anywhere, but its internal variables can only be accessed in {...}, and function foo2 means that foo2 can only be accessed in {...}, others The location is inaccessible, and its internal variables can only be accessed in {...}.

The function scope can be regarded as a bubble, no matter whether the function is executed or not, the internal variables cannot be accessed outside the function (ps: except for closures). For example, the following code will reportReferenceError: a is not defined

function bar(){
    var a=2;
}
bar();	//无论bar有没执行,a变量都无法在外部获取
console.log(a)

When a nested function is encountered, the engine will look up layer by layer from inside to outside, such as:

function bar(){
	var a=2;	//局部变量 a
    function next(){
    	var b=a;
        console.log(b);
    }
}
bar();	//执行bar最终输出b的值为2

Function scope will hide the internal implementation. When the function is executed, the life cycle of internal variables will also end (ps: except for closures) without polluting the external scope.

Block scope

Block-level scope has no such concept in ES5, but some syntax of ES6 adds color to js. The block-level scope can also be regarded as a bubble, and the declared variable cannot leave the bubble. With block-level scope, the effective range of the variable can be accessed within the range of {...}.

Variables declared with let and constants declared with const will automatically hijack the block-level scope, such as:

if(true){
	let a=3
}
console.log(a)	//ReferenceError: a is not defined

for(let b=0;b<3;b++){
	console.log(b)
}
console.log(b) //ReferenceError: b is not defined

As the above code converts the letkeyword into a varkeyword, the output situation is another situation. The reason is that the variable declared by let will automatically generate a block-level scope. When the if statement or the for loop is executed, the variable is also destroyed. , The end of the life cycle.

The above is the scope of JavaScript, so how does the js engine perform scope query for free variables?

** We will all talk about the scope query is through the query from the inside out, yes! But pay attention to a prerequisite: the query is from the inside to the outside in the scope when the definition identifier is created. **

For example:

var a = 100
function F1() {
    var b = 200
    function F2() {
        var c = 300
        console.log(a) // a的查询顺序F2=>F1=>window
        console.log(b) // a的查询顺序F2=>F1
        console.log(c) // c的查询顺序F2=>F1=>window,没找到报(ReferenceError)
    }
    F2()
}
F1()

The following code fn is defined in the global scope, so the value of x is 10. ** The value of x has nothing to do with where fn is called, it is related to where fn is defined and created**.

var x = 10
function fn() {
  console.log(x)	//x的查询顺序fn=>window
}
function show(f) {
  var x = 20;
  (function() {
    f() //10,而不是20
  })()
}
show(fn)

Supplement : Scope search is to query from the inside to the outside, remember that its query rules are specified when the definition is created. This also verifies the concept that js is a static scope. It and execution context are two different concepts. (Ps: do not confuse)

The execution context is based on where the execution is called to determine the execution of the above, it is dynamic. Remember to remember! !

to sum up

After learning the scope of JavaScript again, I have a new understanding of knowledge. Recording and sharing is a great process. See you in the comment section if you have new insights and questions! Next time I will share a special structure like scope closure~~

In addition, I did a series of front-end interview questions in my spare time. Friends in need can click on the blue letters below to read:

Guess you like

Origin blog.csdn.net/hugo233/article/details/113000219