解释器&&AST
JS引擎在编译的时候不是一行一行编译执行的,它是一段一段的,解释器在解析分为两个过程
1.预编译时候的词法分析和语法分析
2.运行代码这里就很简单的讲一下 预编译的时候词法分析会生成一个词法树,到语法分析的时候会把词法树转化一个抽象语法树 也就是我们常说的AST 里面就包括了我们用的语法行为,比如赋值这类操作.
抛开具体细节,简单来说就是有某种方法可以将 var a = 2; 的 AST 转化为一组机器指令,用来创建一个叫作 a 的变量(包括分配内存等),并将一个值储存在 a 中.这个行为是被分解成2个操作的.
词法作用域&&动态作用域
很多人对JS有一个误解,觉得JS跟C++ java c#一样是动态的,其实不是....JS的是静态作用域也就是词法作用域,函数在运行前执行环境就已经被确定了.因为有个JIT的缘故
两者的区别简单点说就是 词法是函数定义的执行环境,动态是执行函数当前函数的环境
上面都是基础埋点为下面做准备的
函数执行栈||环境栈(Function Stack)
栈这个概念就不解释了 基本的数据结构 FILO的模式
调用栈是干嘛的,它是用来跟踪和记录和管理执行上下文的,那么什么叫做执行上下文,
执行上下文 || 执行环境是一个比喻的词,用于描述运行Javascript代码的环境。定义了变量和函数还有其他有权访问的其他数据,还有它们的行为
PS:下面的VO和AO 表示变量对象和活动对象
_____________________________________________________________________________________________
因为是随讲, 我是按我自己的思路排的。
比如 闭包
function a(){
var b=5;
function c(){
b=6
}
c()
}这是一个闭包吗,从定义看它确实是一个闭包,但并不严格,我们从闭包的产生来看,闭包的特性其实是在函数定义的时候就有了,在函数定义的时候函数就会有一个[[scope]]作用域链,是的!这个是在定义的时候就有了...它包含外部对象的变量对象,比如c[[scope]]作用域链里就有a的变量对象.这个就是词法作用域
function a(){
var b=5;
function c(){
b=6
}
return c
}这个才是真正的闭包,因为作用域的副作用,还保留着a的变量对象,即使执行完a函数 也回收不了内存了
当我们在一个环境进行一个函数的执行的时候,就会创建一个变量对象.
变量对象的创建分为创建前和创建后,一个变量对象包括什么 一个作用域链,一个AO,一个this标志,肯定还有其他XXXX变量,但是我们日常使用中最常用的就是这3个.
创建前:
这些变量是怎么添加进去的,这就是AST和JIT的作用了,AST在创建前就会把抽象语法树解析出来从而创建一个去变量对象,这其实就是函数提升和变量提升的关键
vo={
this:xx,
A0:{
arguments:[],
函数声明,
变量声明,
},
scope:[AO,X[[Scope]]]创建后,
其实就是解析语法树,解析个个变量的行为.然后再替换一下VO对象给个个变量赋值一下.
这里有不一样的,作用域链在创建的时候 其实只是把首部加了个自己的活动对象,第二个开始就是外部函数 外部的外部的函数 外部的外部的外部的函数的变量对象 这个时候变量对象=活动对象,也就是说添加的其实就是活动对象.就是AO.
高考语文150的散讲,谁赞成,谁反对