Home >Web Front-end >JS Tutorial >Take you step by step to understand the variables and lexical environment in Javascript

Take you step by step to understand the variables and lexical environment in Javascript

青灯夜游
青灯夜游forward
2020-07-07 15:54:273490browse

Take you step by step to understand the variables and lexical environment in Javascript

In fact, I think the important thing in the core of Javascript is not the advanced syntax extended from the old version, such as destructuring assignment, expansion syntax and remaining parameters (well... although It's indeed very 666), but using these well is actually based on your understanding of variables (people often don't know the difference between an lvalue or an rvalue). Because of this, I think understanding a Javascript should start from the most basic, which is to understand what variables are.

This article is actually not completely basic. It is still based on a certain understanding of Javascript, at least a certain understanding of objects. let's start.

Variables and Data

What are variables?

The simpler the answer to the question, the more surprising it is. Most people's answers are related to the

value; in fact, the variable is the storage area that the program can operate. (Term memory space) , when the Javascript program is running, the storage area (term is memory space) can save anything we need, code, data...etc. Then the data stored in the variable can be roughly divided into two categories: original type (same as the basic type) and reference type; data taken out from the variable It is the value. When you put a value into the variable , the value becomes data again. Javascript is similar to other languages. Variables also need to be declared to actually exist. The declared variable is called

instantiation

. When a value is assigned to the variable (the default is undefined), it is called It is the initialization of variables. The variables that are instantiated but not initialized are in the uninitialized state. For example:

let a = a ;         // (*)
console.log(a);
// ReferenceError: can't access lexical declaration `a' before initialization

perfectly reports an error (at the position of the

(*)

mark), prompting us that this variable cannot be used without initialization. This is different from low-level variables such as C. In fact, this phenomenon has a very fancy name in Javascript: Temporary Dead Zone. I will explain the reasons in a few chapters. (I forgot to mention that a variable declaration also needs a name. The term is called an identifier. I don’t think it will affect anything if I don’t add it...)

But another special thing about Javascript is that , it can

automatically initialize

the variables declared by var, and Javascript will automatically assign an undefined value to the variables declared by var. For example:

var a = a;console.log(a);    // undefined.

Look, they are obviously similar, but the results are completely different. But it is actually of no use. See the following code:

var a = a;console.log(a+2);   // NaN

The result is NaN

, which is a result we don’t want at all. When if the mathematical calculation fails, Javascript will give a non-number result, represented by NaN. But what’s more interesting is that if you use typeof to verify the NaN type: <pre class="brush:php;toolbar:false">typeof NaN ;      // number</pre> tells us that this

TMD

is a numericnumber. There are many inexplicable things about Javascript, but we should stop teasing javascript and start studying it seriously.

Types and StorageJavascript has a total of 7 primitive types and 1 reference type, as follows:

Original type
    1, number
  • 2, string

    3, boolean

    4, symbol

    5, bigint

    6, undefined

    7, null

    Reference type:
  • object
  • (I use lowercase letters here, Because
typeof

returns lowercase) I just introduce these things that you must understand. There are other materials on specific usage, so I won’t go into details. But one thing to add about typeof
is that for null and function the result is: <pre class="brush:php;toolbar:false">function sayHello(){      console.log('hello the world');  }  console.log(typeof sayHello);  // function  console.log(typeof null);      // object</pre>...For a function, it What is really returned is a "function", which is very useful in a sense. However, returning an object to a null value can only be said to have its advantages and disadvantages.

I think the way to deepen our understanding of variables is to understand how they work at the bottom. In fact, there is nothing remarkable. The original value is placed directly in the

memory stack area

, and the reference type value is placed in the memory heap area (this is its actual storage area location); (If it is a constant, it will be placed in the pool, and it seems to be part of the stack area). Under normal circumstances, variable values ​​are obtained directly from the memory stack area, but the reference type value is placed in the memory heap, so what should I do? Take you step by step to understand the variables and lexical environment in Javascriptccess to reference type values:

1. Take you step by step to understand the variables and lexical environment in Javascript reference type variable will save a pointer in the

memory stack

2. This pointer It is the memory address used to reference the storage area in the memory heap

3. When accessing a type value

4、会通过指针找到内存堆中的存储区,然后从中获取值。

例如:

  var first  = {
      name:'hahei...'
  }
  var gggiii=111222;

映射图如下:

Take you step by step to understand the variables and lexical environment in Javascript

注意:此处我用 ref. first表示  存储区的引用 , 因为虽然保存的尽管是指针,但是在访问这个值时,会进行二次解析(即通过这个指针找到存储区), 而不是直接返回这个指针的具体数据。详细可以参考 C++引用。

初识词法环境

想必各位都已经对什么是作用域了若指掌,但是我还是必须重新提一下作用域标识符的可访问范围,在Javascript中的任何操作,几乎都有作用域的参与。Javascript中使用词法环境决定作用域,在下面我会简单介绍一下。(请注意,这里我没有用变量这个术语,因为解析标识符范围时,应该还没有真正生成代码,感兴趣的可以去了解一下Take you step by step to understand the variables and lexical environment in JavascriptST语法树

看,以下代码:

 var val=111;
 function hahaha(){
     console.log(val);
 }
 function hihihi(){
    hahaha();
 }
 hihihi();  /// 111

的确是正确输出了,111

但是我更喜欢把 val放在一个函数中,如:

   function hahaha(){
       console.log(val);      /// (**)
   }
   function hihihi(){
      var val=111;            /// (*)
      hahaha();
   }
   hihihi();

结果就是Uncaught ReferenceError: val is not defined, 根本没找到val这个标识符,这是为什么?

因为执行过程是这样的:

  1. hihihi函数执行  , 然后为 val赋值……
  2. hahaha函数执行
  3. hahaha找不到val标识符,便去外部词法环境
  4. hahaha外部词法环境就是** hahaha函数声明时代码的外部**,即全局代码(下称全局词法环境)
  5. 全局词法环境没找到val,终了。
    (请注意3-5步, 找val找的是函数声明代码的外部,而不是函数调用时的位置。)

现在应该提一下概念了,词法环境(Lexical Environment)就是根据代码结构时决定的作用域,也可以称作词法作用域(Lexical Scoping)它是静态作用域。可以这么说,在源代码写好时,所有标识符的作用域就已经被决定。当然也有动态作用域,你可以去试试bash脚本,它就是动态的。嘿嘿。详细也可以参考静态作用域词法作用域

此处只要发现了个中区别就极好掌握,所以我就略了。

词法环境的抽象

在Javascript常用三种词法环境: 一、块级作用域 二、全局作用域 三、函数作用域。

有时,我们会将一个词法环境(即作用域,下面我会正式使用词法环境替代作用域这个术语)抽象成伪代码,如下:

	LexicalEnvironment = {
		OuterEnv:  ,
		This :    ,
		EnvironmentRecord:{
			// ... identifiername:variable
		}
	}

很简单:

  • OuterEnv:当前词法环境的外部词法环境
  • This: 当前词法环境的 this的值,但它是运行时决定的。
  • EnvironmentRecord(环境记录): 标识符-变量的映射,注意,这里的标识符只是单纯的字符串,变量指的是存储区的数据。而且标识符必须是当前词法环境,而不是当前代码的。

例如:

  function first(){
      var a  =100;
      let d = 220;
      {     // Block, 
          var b = a+100;
          let c = b*10;
          console.log(a,b,c,d);
      }
  }
  first();  // 100 200 2000 220

一定不要忽略first函数中的块级作用域,这很重要。

然后写成抽象就是:
函数内部的块级作用域

	BlockEnv = {
		OuterEnv:  ,
		This :    ,
		EnvironmentRecord:{
			c:              // 这里没有b
		}
	}

函数作用域

	FuncEnv = {
		OuterEnv:  ,
		This :    ,
		EnvRec:{
			a:,
			d:,
			b:
		}
	}

OKay,先到这里吧。

一些问题:

1、为什么用词法环境代替作用域
–词法环境涵盖了作用域,但反之则不能。
–但注意,词法作用域和词法作用域链与作用域以及作用域链都可通用。

2、环境记录是什么?
–当前环境下的标识符-变量的映射
–但是标识符只是“合法标识符”的字符串形式。
–变量是是指存储区的内容,但是确切说法是存储区

最后

我把我的笔记,重新整理后发到博客上后发现——我笔记干净了好多,艹。

This kind of content that only goes deep into the core is very useful, and it also becomes much more flexible when writing code. I think this is the most useful place. Finally:
My personal understanding is that I often make mistakes; if I look closely I don’t know where to look, I hope you will be aware of it.

This article is reproduced from: https://blog.csdn.net/krfwill/article/details/106155266

Related tutorial recommendations:

JavaScript video tutorial

The above is the detailed content of Take you step by step to understand the variables and lexical environment in Javascript. For more information, please follow other related articles on the PHP Chinese website!

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