Variable scope

JavaScript Variable scope (JavaScript变量作用域)

JavaScript is one of the most function-oriented programming languages. In JavaScript, it is possible to create a function, dynamically passed as an argument to another function, and called from a different place of code after. Variable scope is one of the first things to learn in JavaScript.The location of the variable declaration controls the scope of a variable. The variable scope is targeted at defining the part of the program where a variable can be accessible. (JavaScript是最面向函数的编程语言之一。 在JavaScript中,可以创建一个函数,作为参数动态传递给另一个函数,并在之后从不同的代码位置调用。 变量作用域是JavaScript中首先要学习的内容之一。变量声明的位置控制变量的作用域。 变量作用域旨在定义程序中可以访问变量的部分。)

JavaScript has two types of variable scopes: global and local. Any variable that is declared outside of a function can be related to the global scope, and it’s accessible from everywhere in the code. Every function should have its scope, and any variable declared in that function can be accessible from that function only, or nested functions. As in JavaScript, the local scope is also made by functions, we can also call it a function scope. Whenever you put one function inside another function, you create a nested scope.

Code Blocks

Code Blocks (代码块)

In case a variable is declared inside a code block {…}, it can be visible inside the block.

For instance:

{
 // work with the local variables that must not be seen outside
(//使用不能在外面看到的局部变量)
 let showWelcome = "Welcome to w3cdoc"; // only visible in this block 
 console.log(showWelcome); // Welcome to w3cdoc
}
console.log(showWelcome); // Error: showWelcome is not defined

If you want to isolate a part of a code doing its task, with variables belonging to it:

{
 // show message
(显示消息)
 let showMessage = "Welcome to w3cdoc";
 console.log(showMessage);
}
{
 // show another message
(//显示另一条消息)
 let showMessage = "Тhis's a training site";
 console.log(showMessage);
}

Without isolated blocks, an error could occur, in case we apply let along with the name of the variable:

// show message
let showMessage = "Welcome to w3cdoc";
console.log(showMessage);
// show another message
let showMessage =  "Тhis's a training site"; // Error: variable already declared
console.log(showMessage);

For while, if, for, and more, the variables that are declared in {…} can only be visible inside.

It’s visualized in the following example:

if (true) {
 let showMessage = "Welcome to w3cdoc";
 console.log(showMessage); // Welcome to w3cdoc
}
console.log(showMessage); // Error, no such variable!

Here, after if ends, the console.log can not see the showMessage and the error. (在这里,如果结束, console.log将无法看到showMessage和错误。)

Here is a similar case with while and for loops:

for (let i = 0; i < 10; i++) {
//the i variable can only be seen inside this for
(//i变量只能在这里面看到)
  console.log(i); // 0, then 1, …, then 9
}
console.log(i); // Error, no such variable

Nested Functions

Nested Functions (嵌套函数)

As you already learned, we call a function “nested” when it’s made inside another function. JavaScript allows you to do it in an entirely natural way. In general, you can use it for organizing your code, as follows:

function user(firstName, lastName) {
 // helper nested function to use below
(//下面要使用的helper嵌套函数)
 function getFullName() {
   return firstName + " " + lastName;
 }
 console.log("Welcome to w3cdoc, dear " + getFullName());
}
user("David", "Brown");

The most exciting thing about a nested function is that it can be returned. A nested function can be returned as a new object property or as a result. Then you can use it somewhere else.It is visualized in the example below:

function addCounter() {
 let count = 0;
 return function () {
   return count++;
 };
}
let counter = addCounter();
console.log(counter()); // 0
console.log(counter()); // 1
console.log(counter()); // 2

Lexical Environment

Lexical Environment (词汇环境)

Every running function, code block, and the script have an obscure associated object, called Lexical Environment. (每个正在运行的函数、代码块和脚本都有一个模糊的关联对象,称为词法环境。)

The object of Lexical Environment includes the following two parts:

  • Environment Road- an object storing all the local variables as its properties. (- Environment Road -将所有局部变量存储为其属性的对象。)

  • The outer lexical environment reference. (-外部词汇环境参考。)

For clarity, we have split the explanation into 4 steps. (为了清楚起见,我们将解释分为4个步骤。)

Step 1. Variables

Step 1. Variables (第1步:变量)

A variable is a special internal object property, Environment Record. (变量是一个特殊的内部对象属性,环境记录。)

It is known as the global Lexical Environment, linked with the whole script. The rectangle, in the example above, means Environment Record, and the arrow- the outer reference. There is no outer reference for the global Lexical Environment, hence the arrow points to null. (它被称为全局词法环境,与整个脚本相关联。 在上面的示例中,矩形表示环境记录,箭头表示外部引用。 全局词法环境没有外部引用,因此箭头指向null。)

In general, Lexical Environment can be described as a specification object existing only theoretically to describe how things work. It is not possible to get it in code and directly manipulate it. (一般来说,词汇环境可以被描述为仅在理论上存在的规范对象,以描述事物的工作原理。不可能在代码中获取并直接操纵它。)

Step 2. Function Declarations

Step 2. Function Declarations (步骤2.函数声明)

A function can also be considered as a value. But, note that a Function Declaration is fully initialized at once. (函数也可以被视为一个值。但是,请注意,函数声明立即完全初始化。)

At the time a Lexical Environment is generated, a Function Declaration instantly becomes a function ready for usage. (在生成词法环境时,函数声明立即成为可供使用的函数。)

It can only apply to Function Declarations, not Function Expressions, where a function to a variable is assigned, like this:

let say = function(name)…. (let say = function (name)….)

Step 3. Inner and Outer Lexical Environment

Step 3. Inner and Outer Lexical Environment (第3步:内外词汇环境)

Whenever a function runs, at the start of the call, a new Lexical Environment is made automatically for storing local parameters and variables of that call. (每当函数运行时,在调用开始时,都会自动创建一个新的词法环境,用于存储该调用的本地参数和变量。)

There are two Lexical Environments during the call: the inner and the outer. The inner one matches the current execution of say. The only property it has is name.The outer Lexical Environment is the global one that has the phrase variable and the function itself. The inner one has a reference to the outer.

If a code wants to enter a variable, it is necessary to look for the inner Lexical Environment first, then the outer one, then the more outer one. These actions continue until reaching the global one. (如果代码想要输入变量,则必须首先查找内部词法环境,然后查找外部词法环境,然后查找更外部的词法环境。这些操作将持续进行,直至达到全球标准。)

Step 4. Returning a Function

Step 4. Returning a Function (第4步:返回函数)

Now, let’s start from the addCounter case:

function addCounter() {
 let count = 0; 
 return function () {
   return (++count);
 };
}
let ctr = addCounter();
console.log(ctr());

At the start of this call, a new Lexical Environment object is generated for storing variables for the addCounter run. (在此调用开始时,将生成一个新的词法环境对象,用于存储addCounter运行的变量。)

The most notable difference is that during the invocation of the addCounter(), a small nested function is generated merely on the line return ++count. Consider that all functions remember the Lexical Environment they were created in. That’s because all the functions have concealed property, known as [[Environment]], keeping the reference to the Lexical Environment where the function was made. (最明显的区别是,在调用addCounter ()期间,仅在return + + count行上生成一个小型嵌套函数。 考虑所有函数都记住在其中创建的词法环境。 这是因为所有函数都具有隐藏属性,称为[[Environment]] ,保留了对生成函数的词法环境的引用。)

The counter.[[Environment]] includes a reference to the Lexical Environment {count: 0}. The reference [[Environment]] is established once and forever during the function creation.

After, a new Lexical Environment is made for the call, which external Lexical Environment reference is taken from the counter.[[Environment]]. (之后,为调用创建一个新的词法环境,从计数器中获取外部词法环境引用。[[环境]]。)

Any variable can be updated in the Lexical Environment it exists in. In the event of calling counter() several times, the variable count increases to 2, 3, and more. (可以在它所在的词法环境中更新任何变量。 在多次调用counter ()的情况下,变量count增加到2、3等。)



请遵守《互联网环境法规》文明发言,欢迎讨论问题
扫码反馈

扫一扫,反馈当前页面

咨询反馈
扫码关注
返回顶部