Home>Article>Web Front-end> 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 actuallybased 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 acertain understanding of Javascript, at least a certain understanding ofobjects. 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 thevalue; in fact, the variable is the storage area that theprogram 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) andreference type; datataken out from the variable It is the value. When you put a valueinto 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 theinitializationof variables. Thevariablesthat are instantiated but not initialized are in theuninitializedstate.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 thatthis 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 initializethe variables declared byvar
, and Javascript will automatically assign an undefined value to the variables declared byvar.For example:
var a = a;console.log(a); // undefined.
var a = a;console.log(a+2); // NaN
, which is a result we don’t want at all. Whenif the mathematical calculation fails
, Javascript will give anon-numberresult, represented byNaN. But what’s more interesting is that if you usetypeof
to verify theNaN
type:
tells us that thistypeof NaN ; // number
is anumericnumber.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 type2, string
3, boolean
4, symbol
5, bigint
6, undefined
7, null
Reference type: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 fornull
andfunction
the result is:
...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.function sayHello(){ console.log('hello the world'); } console.log(typeof sayHello); // function console.log(typeof null); // object
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 thememory heap area(this is its actual storage area location); (If it is aconstant, it will be placed in thepool, and it seems to be part of the stack area). Under normal circumstances, variable values are obtained directly from thememory stack area, but the reference type value is placed in thememory 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 stack2. This pointer It is the memory address used toreference the storage areain the memory heap
3. When accessing a type value
4、会通过指针找到内存堆中的存储区,然后从中获取值。
例如:
var first = { name:'hahei...' } var gggiii=111222;
映射图如下:
注意:此处我用 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
这个标识符,这是为什么?
因为执行过程是这样的:
hihihi
函数执行 , 然后为val
赋值……hahaha
函数执行hahaha
找不到val
标识符,便去外部词法环境hahaha
外部词法环境就是** hahaha函数声明时代码的外部**,即全局代码(下称全局词法环境)3-5
步, 找val找的是函数声明代码的外部,而不是函数调用时的位置。)现在应该提一下概念了,词法环境(Lexical Environment)就是根据代码结构时决定的作用域,也可以称作词法作用域(Lexical Scoping)它是静态作用域。可以这么说,在源代码写好时,所有标识符的作用域就已经被决定。当然也有动态作用域,你可以去试试bash脚本,它就是动态的。嘿嘿。详细也可以参考静态作用域、词法作用域。
此处只要发现了个中区别就极好掌握,所以我就略了。
词法环境的抽象
在Javascript常用三种词法环境: 一、块级作用域 二、全局作用域 三、函数作用域。
有时,我们会将一个词法环境(即作用域,下面我会正式使用词法环境替代作用域这个术语)抽象成伪代码,如下:
LexicalEnvironment = { OuterEnv: , This : , EnvironmentRecord:{ // ... identifiername:variable } }
很简单:
this
的值,但它是运行时决定的。例如:
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/106155266Related tutorial recommendations:
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!