作用域
GO/AO产生的一系列关于问题。 如何利用AO/GO去说明一些问题。
AO->function ->独立的仓库
- 对象
- 属性
- 方法
- 函数也是一种对象类型,引用类型(Object,Array,Function),引用值。
- 属性
- name
- length//形参个数
- prototype
- 属性
对象的属性无法访问
函数被创建的时候产生了一个js内部的隐式属性(只能被js引擎读取)。
- 函数存储作用域链的地方。 作用域链里存储的是AO/GO
- AO 函数的执行期上下文
- GO 全局的执行期上下文(包含了 window 函数声明,变量声明)
- 函数执行完成之后,就会销毁自己的AO。再次执行会重新生一个新的AO
- AO 是一个即时存储容器
- 全局执行前一刻,生成了GO->全局函数被定义的时候生成了自己的作用域和作用域链。
[[scope]] scope chain(作用域链)
GO
function a(){function b(){var b = 2;}var a = 2;b();}a();
- 解释
- 全局在执行的时候,a被定义的时候生成了一个[[scope]]属性的时候,scope 里面存储作用域链。
- scope作用域 第0位存储的是GO;
- a执行的前一刻 生成了自己的AO 此时a函数作用域链第0位存储的是a函数的AO. 第二位是全局GO;
- b在被定义是-> b函数的作用域链
分析作用域链
function a(){function b(){function c(){}c();}b();}a();/**** a 定义:a.[[scope]] -> 0:GO* a 执行:a.[[scope]] -> 0:a的AO* 1:GO** b 定义 b.[[scope]] -> 0:a的AO* 1:GO** b 执行 b.[[scope]] -> 0:b的AO* 1:a的AO* 2:GO** c 定义 c.[[scope]] -> 0:b的AO* 1:a的AO* 2:GO** c 执行 c.[[scope]] -> 0:c的AO* 1:b的AO* 2:a的AO* 3:GO** c 结束 c.[[scope]] -> 0:b的AO* 1:a的AO* 2:GO* b 结束 b.[[scope]] -> 0:a的AO* 1:GO* a 结束 a.[[scope]] -> 0:GO*/
闭包
- 当内部函数被返回到外部保存的时候,一定会产生闭包
- 闭包会产生,原来的作用域链不释放
- 过度闭包可能会导致内存泄漏,加载过慢
例子
function test1(){function test2(){var b = 2;console.log(a);}var a = 1;return test2;}var test3 = test1();test3();/**** 事件 作用域[[scope]] 作用域链scope chain* test1 被定义的 test.scope 0:GO* test1 执行前一刻 test.scope 0:test.AO* 1:GO* tes1 执行* test2被定义 test2.scope 0:test.AO* 1:GO* test1 执行完毕 test1.scope 0:GO** test3执行前一刻 test2生成了自己的AO 0:test2.AO* 1:test1.AO* 2:GO;* test3 执行* test3 执行完毕 GO 0:test1.AO test1的AO一直未被释放* 1:GO*/
function test(){var n = 100;function add(){n++;console.log(n);}function minus(){n--;console.log(n);}return [add,minus];//或者下面那个。return {add,minus}}var arr = test();arr[0]();//101arr[1]();//100/***** 全局预编译的时候生成GO* 作用域链* test 被定义 0:GO* test 执行前一刻 0:test.AO* 1:GO* test 被执行 test.AO={n:100,add:function(){},minus:function}** add 被定义 0:test.AO* 1:GO* minus 被定义 0:test.AO* 1:GO* add minus 被返回出去。形成闭包* test 执行完毕 0:GO** add执行前 0:add.AO* 1:test.AO* 2:GO* add执行后 0:test.AO* 1:GO*/
