预编译
G0 & Ao
GO: 页面创建后就会自动创建一个全局对象(Global Object)
浏览器环境里GO:window;node环境里GO:global
里面存放着许多原始的属性和方法(例如:Arrary;Date;console.log()…..)
AO: 函数在执行前创建的活动对象 (Active Object)
一.预编译
例子:
1 | var a = 20 |
- 代码执行前首先会进行预编译
- 查找变量声明,作为GO属性,值赋予undefined;
- 查找函数声明,作为GO属性,值赋予函数体;
- 执行代码
- 解释一句执行一句
- 执行过程中肯定会修改所在活动对象里面的属性的值(个人理解)
二.作用域
2.1全局作用域
GO: {
}
2.2局部作用域(函数作用域)
AO: {
}
三.作用域链
例如:
1 | var a = 10 |
执行此段代码之前,各个函数其实已经在预编译阶段有了自己的作用域链
- b函数 b-AO —-> GO
- c函数 c-AO —–> b-AO —–> Go
- c执行的时候,由于自己的AO里面没有变量a,会依次向上寻找变量a
- 如果找到就打印结果
- 没有找到就打印undefined (或者报错 a is not defind)
四.变量提升
- 用关键字 var 声明的变量 在预编译阶段会提升到当前所在代码快的最前面
五.函数提升
- 用function关键字声明的函数 在编译阶段也会进行提升
六.闭包
定义:在函数内部被返回的函数并且被保存到外部 那么就形成了闭包
闭包列子:
1 | var arr; |
- 输出结果: 10 10 10 10 10 10 10 10 10 10
- 原理: 由于函数被保存的数组里面 并且被返回出来 所以形成了闭包
- 当执行完for循环的时候 知识为arr每一个元素赋值为一个函数
- 在函数执行是 内部的i才会被赋值 此时i已经为10了
解决方案:
1 | var arr; |
结果: 0 1 2 3 4 5 6 7 8 9
原理: 利用一个立即执行函数 让arr的每一个函数与立即执行函数形成一个闭包 在arr被执行的时候,就会利用闭包里面的值j