本文文字内容比较多,需要详细认真阅读,如有不懂或建议可以留言~
前两天一个学生问了一个问题:
var a =1;
var a =18;
在内存中是啥样的?
第一:是后面会把前面那句覆盖,栈中只有一个空间,变量a,值为18
第二:是栈中有两个空间,都放着a。哪种?
当然,这个问题的前提是两次声明都应该是在同一个作用域下的。
那首先以下的问题应该怎么回答?
这些变量在哪里?它们储存在哪里?程序需要时如何找到它们?
在回答这个之前你需要了解一些知识点:
- 引擎
从头到尾负责整个 JavaScript 程序的编译及执行过程。- 编译器
引擎的好朋友之一,负责语法分析及代码生成等脏活累活- 作用域
引擎的另一位好朋友,负责收集并维护由所有声明的标识符(变量)组成的一系列查 询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。
---摘自 Kyle Simpson
加入现在以一个代码 var a=1;
,那么浏览器怎么工作的呢?
- 它将var a和 a = 1 当作两个单独的声明,第一个是编译阶段的任务,而第二个则是执行阶段的任务。
- 在当前作用域中的声明出现在什么地方,都将在代码本身被执行前首先进行处理。 可以将这个过程形象地想象成所有的声明(变量和函数)都会被“移动”到各自作用域的最顶端,这个过程被称为声明提升。(后边的的博客会详细的讲解,
js声明提升机制
)
所以声明a就会在当前作用域的最前边执行(无论你的var a=1
之前有多少个代码)。- 首先遇到 var a,编译器会询问作用域是否已经有一个该名称的变量存在于同一个作用域的集合中。如果没有它会要求作用域在当前作用域的集合中声明一个新的变量,并命名为 a,然后运行到
a=1
的时候,就会进行一个LHS查询( LHS 查询则是试图找到变量的容器本身,从而可以对其赋值)
引擎运行时会首先询问作用域,在当前的作用域集合中是否存在一个叫作 a 的 变量。如果有,引擎就会使用这个变量会把 1 赋值给 变量a,并将1保存在栈区中(后边的基本类型和引用类型会讲解栈区和堆区的储存),如果没有就另当别论,不是今天讨论的内容(是作用域链的知识点了)。- 但是遇到 var a时,发现当前作用域已经定义了变量a,那么编译器会忽略该声明,当作什么都没有发生,然后继续编译后边的代码。
所以上边的问题你懂了么?
今天浪了一天,太晚了~就这些吧~晚安
![](https://img.haomeiwen.com/i3532891/935a702a9bb45b45.png)
网友评论