重温JS——预编译、全局预编译、作用域链

目录

一、预编译

1、分析代码是否正确、符号、词法分析等

2、隐式操作==>预编译==>  (形 [形参、变量]  实 函 运 )

3、运行代码:

二、全局预编译

三、作用域链


一、预编译

1、分析代码是否正确、符号、词法分析等

2、隐式操作==>预编译==>  (形 [形参、变量]  实 函 运 )

函数再调用之后,在运行代码之前会生成一个对象==>  执行期对象AO==> activation Object(执行期上下文)==>每次调用就会创建一个AO对象

形:将 函数内部的 局部变量 和 形参变量 添加到AO对象内,作为AO对象的属性名。但是属性值是undefined。==》变量和形参名提升

实:把传入的实参赋值给AO对象的属性(如果实参是变量,那应该先取值后再传入)

函:局部函数声明、赋值。把局部函数的名字让AO对象也有一个一样的成员名,把函数体赋值给这个属性。==>函数整体提升
 

3、运行代码:

运:运行代码。

函数运行完毕,AO就释放了

二、全局预编译

全局作用域运行代码时,也有预编译==>   全局预编译==>  形 [变量]  函  运 

1、生成一个对象Global Object (   GO:{  }   )

2、把所有的全局变量设置为GO的属性名

3、把所有函数名作为GO的成员名,把哈桑农户体赋值给这个成员

全局编译还有一步,不同的环境中JS代码不一样

如果是浏览器,还会执行异步GO给window对象共享成员

GO对象的成员全部浅拷贝给环境对象window  (node.js 环境中没有这一步)

4、执行代码

拓展:关于访问成员:

console.log(a) 访问的是GO对象的成员,如果作用域链中都没有就报错

console.log(window.a) 原型链上如果都没有就返回undefined,不会报错

三、作用域链

closure:闭包

JS对象有两种成员:

1、上文成员(JS语法可以直接访问的成员)

2、下文成员(底层语法访问的成员)==>    [[]]括起来的成员名,就是下文成员

函数的属性: length、name、[[scoped]]  ==> 

[[scoped]]  ==> 这个“对象”内存保存的就是函数的作用域。可以通过console.dir(fn)看见。

函数在定义/声明的时候,就有了[[scoped]]   (只能引擎使用),里面保存了上层的AO对象

==> 函数调用时会生成AO对象,AO保存在[[scoped]] 对象内部,每次调用都会放在scoped的上面,先放的就放在下面

每个函数scopes数组天生就有一个AO对象,就是这个函数的上层的AO

总结:

函数定义/声明  ==>  生成scopes,并将本来就有的GO/AO放入到scopes的最下面

函数调用          == >  生成AO

            function fn(a) {
                function fm() {
                    var b=20
                    console.log(a)
                }
                fm()
            }
            var c=2
            fn(10)
            fn(20)

AO会被销毁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值