Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Explain the scope of JavaScript in detail

2025-02-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly introduces "detailed interpretation of JavaScript scope". In daily operation, I believe many people have doubts about explaining JavaScript scope in detail. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts of "detailed interpretation of JavaScript scope"! Next, please follow the editor to study!

JavaScript compilation process

Before learning the scope, let's take a brief look at the compilation and execution of JavaScript.

JavaScript is called an interpretive language, which is different from compiled languages such as Java in that JavaScript code can be executed immediately after it is written, while Java takes a relatively long time to generate executable machine code.

But in fact, JavaScript also has a compilation process, JavaScript uses a just-in-time compilation method (JIT). JIT compiles the code in the JavaScript code that will run multiple times to the compiler, generates the compiled code and saves it, and uses the compiled code the next time it is used. This is actually an optimized solution adopted by the JavaScript runtime environment. If you do not do so, a large number of repetitive code will be recompiled before running, which will greatly affect performance and efficiency.

The JavaScript engine will also pre-compile the JavaScript code before it is run, and define a set of rules to store variables, objects, functions, etc., in the process of pre-compilation. This set of rules is scope.

JavaScript engine has to do a series of work such as lexical analysis, syntax analysis, code generation, performance optimization and so on. JIT is part of this process that is used to optimize.

Var a = 1

Var a = 1; what does the compiler do before the code runs?

The compiler will divide this line of code into var an and a = 1.

First of all, the compiler will query in the same scope whether a variable already exists, if so, the compiler will ignore the declaration of an and proceed to the next step of compilation; if not, declare a variable in the current scope and name it a.

The compiler then generates runtime code for the engine, which contains parts that deal with a = 1. When dealing with a = 1, the engine will also query whether there is a variable an in the scope (it will look up the scope step by step), assign a value to 2 if it does not exist, and throw an exception (in strict mode, if not strict mode will implicitly create a global variable ascape LHS).

LHS query & RHS query

LHS and RHS mean "left and right of the assignment operation," but note that they do not refer only to "=" and to the left and right. There are other forms of assignment, so it can be understood as: who is the goal of the LHS- assignment? RHS- who is the source of the assignment operation.

A = 1; is the query for a LHS, and an is the target of the assignment operation, which assigns a value of 1. If the LHS query fails, a global variable is implicitly created in non-strict mode, and ReferenceError: an is not defined is thrown in strict mode

Console.log (a) is the query for a RHS, and an is the source of the assignment; if an is not queried in the scope chain, ReferenceError: an is not defined is also thrown

Domain chain

Scope is a set of rules for storing variables, and when the code runs, it may not just query variables in one scope. Scope nesting occurs when one scope contains another scope. So when the internal scope cannot find a variable, the engine continues to query in the outer nesting of the current scope until the variable is found or the outermost scope is reached. This is the scope link.

Var name = "rewa"; function sayHi () {console.log ("hello," + name);} sayHi (); / / hello,rewa

As in the above code, there is no variable name; in the scope of the sayHi function, but it can be referenced normally. Because the engine found and used the variable name in the upper scope

Var name = "rewa"; function sayHi () {var name = "fang"; / / added code console.log ("hello," + name);} sayHi (); / / hello,fang

When the variable name has been found in the sayHi scope, the engine stops looking for the upper scope, which is called the "masking effect", and the internal variable obscures the external scope variable.

Lexical scope

There are two main working models for scope. One is the most common lexical scope used by most programming languages, and the other is called dynamic scope.

Lexical scope is the scope where variables and blocks are written when writing code, which is defined in the lexical stage. JavaScript is the lexical scope used.

Morphology: a string that makes up a block of code. For example:

Var a = 1

In this line of code, var, a, =, 2, and the spaces in the middle are all lexical units.

The first job of the compiler is lexicalization, which breaks down the code into lexical units; what the compiler does during the lexicalization phase and which rules it obeys varies from programming language to programming language. I don't know what the rules of JavaScript are. I'll take a note when I figure it out.

To put it simply, the lexical scope is that when you write the code, write the variable an in the function b, then the compiler compiles the scope of b will contain the variable a, and the compiler will keep the lexical scope unchanged. (there will also be special circumstances.)

The code is as follows:

Var a = 1 var function foo () {var b = a + 2; function bar () {var c = b + 3; console.log (areco bjort c)} bar ();} foo (); / / 1meme 3Jing 6

The compiled scope of this code is consistent with the lexical scope when you wrote it.

Global scope: variable a, function foo

Scope created by function foo (): variable b, function bar

The scope created by the function bar (): variable c

The scope is wherever the code is written.

To understand the lexical scope, you need to pay attention to the following points:

No matter where the function is called and how it is called, the lexical scope of the function is determined only by where the function is declared.

Lexical scope queries only look for first-level identifiers, such as the variable a _ c in the above code. If you access foo.bar.baz, the lexical scope only queries foo. After finding this variable, access the property bar, and then go to baz.

There are ways to make lexical scopes inconsistent after compilation, but can lead to performance degradation.

The method of modifying lexical scope eval & with (do not do this) eval

The code is as follows:

Var a = 1 function foo (str) {eval (str); console.log (a);} foo ('var a = 2 politics'); / / 2

Var a = 1; will run in the function foo, and the variable a will contain scope. Eval (...) The function accepts a string and runs the string as code; it is equivalent to writing the code in this location.

Eval throws an exception in strict mode:

Var a = 1 var function foo (str) {"use strict" eval (str); console.log (a); / / ReferenceError: an is not defined} foo ('var a = 2 foo')

By default, if there is a declaration in eval (), the lexical scope will be modified; in strict mode, eval () will have its own lexical scope at run time, so it will not be able to modify the scope, such as the code above.

Withvar obj = {avelle 1, bazaar 2, cveau 3} obj.a = 11 posiobj.b = 22 transobj.c = 33 exodus / with can also achieve the same effect with (obj) {av 111; bang 222; cv 333;} / / so that the obj is modified to: {av 111, b222, cv 333}.

With () takes a parameter, in this case obj;, where the scope in with is obj, and you can access the properties in obj. This way of assigning values becomes much simpler.

With can create a scope for an object, and the object's properties are defined as variables in that scope; however, variables in with declared through var do not become members of this scope, but are declared to the scope where with is located. This is not normal, the code using with will become very difficult to control. For example:

With (obj) {aq111; bread222; cymbals 333; dumb444;} console.log (obj.d); / / undefinedconsole.log (d); / / 444

The attribute d, which was supposed to be added to the obj, is added to the global scope; this may not be consistent with the expected results at the time of development and writing; nor does it conform to the rules of lexical scope.

So both eval and with have been banned and are not recommended.

The nature of this unpredictable lexical scope also brings a serious performance problem. The JavaScript engine performs performance optimizations during the compilation phase. Some of these optimizations rely on code-dependent lexicology, static analysis of lexicology, and pre-determination of the definition location of all variables and functions in order to quickly find variables in the process of execution.

If the engine finds eval or with in the code, it cannot explicitly know eval (...) during the lexical analysis phase. What code to deliver; there is no way to know what object content is passed to with to create a new lexical scope. Then there is no point in optimizing unknown code and lexical scope, and the engine will abandon the optimization part.

If you use eval or with frequently in your code, the program will run very slowly.

Function scope

The variables and function definitions inside the function can be encapsulated, and the variable identifiers encapsulated inside the function cannot be accessed externally.

The code is as follows:

Function foo () {var a = 1; function sayHi () {console.log ('hellograms')}} console.log (a); / / ReferenceError:an is not definedsayHi (); / / ReferenceError: sayHi is not defined

Variables and functions that access their interior outside the function will throw an exception.

In this way, the function can be made into a relatively independent scope, and the function can be used to encapsulate a relatively independent function. Hide the business code inside the function and expose the interface; as long as you pass in different parameters, you can enter the corresponding results. So in many cases, functions can be used to simulate the implementation of classes in the Java language.

For example:

Function shoot (who,score) {/ / this can contain more logic function one () {console.log (who + 'free throw hit! Get a'+ score+ 'score!) ;} function dunk () {console.log (who + 'dunk, get a' + score+ 'score!) ;} function three () {console.log (who + 'hit a' + score+ 'ball!) ;} switch (score) {case 1: one (); break; case 2: dunk (); break; case 3: three (); break;}} shoot ('Kobe',3); / / Kobe made a 3-pointer!' Shoot ('Lebron',2); / / Lebron dunk, get 2 points! Shoot ('Shaq',1); / / Shaq free throw hit! Get a point!'

Hiding the definition of variables and functions within a function can avoid polluting the global namespace; for example, when there are functions such as one dunk three in the global scope and the internal implementation is different, the code logic will be confused. In the above code, the function defined in the function obscures the function definition in the external scope and only calls the function with the same name in the current function scope.

But even so, a large number of function declarations can also pollute the global full-name space. The popular modularization is one of the solutions to this problem. However, before modularization comes out, most cases can be solved using immediate execution functions (IIFE). The code is as follows:

(function () {var name = 'kobe'; console.log (name);}) ()

When the function execution ends, the name variable is garbage collected; it does not conflict with any external scope, because the entire function executes in an immediate execution function. It is a block scope and does not itself create any identifiers under the scope.

Executing the function immediately can also accept parameters, which can be used for internal references to the function:

(function (name) {console.log (name);}) ('kobe')

Besides the function scope, there are other block scopes in JavaScript. For example, with is also block-scoped; with has been introduced above. There is also a block scope try/catch that is easily overlooked.

Try {undefined (); / / throw exception} catch (err) {console.log (err); / / normal execution} console.log (err); / / ReferenceError: err is not defined

Err can only be accessed in catch, and external references throw an exception.

For block scopes, we can implement this requirement with let declarations in ES6.

If (true) {let a = 1; console.log (a); / / 1} console.log (a); / / ReferenceError: an is not defined

If () {} is not block scoped, but let in the above code makes variable a variable only in if () {...} and is not externally accessible.

This is a lot like try/catch, but let is the standard of ES6; implementing block-scoped effects before ES6 is not so easy. Now generally we are writing ES6 code, want to run on all browsers need to be translated. And the translator will also convert statements similar to let into try/catch.

{let a = 1; console.log (a); / / 1} console.log (a); / / ReferenceError: an is not defined

To:

Try {throw 1;} catch (a) {console.log (a); / / 1} console.log (a); / / ReferenceError: an is not defined

It may also be translated into:

{let _ a = 1; / convert an in {} to _ a console.log (_ a);} console.log (a); at this point, the study on "detailed explanation of JavaScript scope" is over, hoping to solve everyone's doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report