预编译:先扫描代码,语法分析

变量 函数提升

函数声明整体提升:函数不管写到哪里,都会被提到逻辑的最前面。所以不管在哪 里调用,本质上都是在后面调用

变量 声明提升,赋值不提升:把 var a 提升到最前面

  1. test();
  2. function test(){
  3. console.log(‘a’);
  4. }
  5. console.log(a); //undefined 不会报错
  6. var a = 123;

全局变量 window global

.imply global 暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为 全局对象(就是 window)所有

a = 10; ===> windows.a = 10;

  1. function test() {
  2. b = 123
  3. }
  4. test()
  5. console.log(b)//123
  6. b = 123
  7. console.log(b)//123
  8. var a = b = 234;
  9. function test(){
  10. var a = b = 123;
  11. }
  12. test()

写 test()代表执行 test,赋值是自右向左的,上面先把 123 赋给 b 的时候,b 未经声明,
然后再声明 a,再 b 的值赋给 a,导致 b 未经声明,所以 b 归 window 所有
访问 window.a 是 undefined,访问 window.b 是 123

一切声明的全局变量,全是 window 的属性,window 就是全局的域
定义全局变量,就是把a放入window对象

var a = 123; ===> window.a = 123;

image.png

预编译过程

函数预编译

预编译发生在函数执行的前一刻

  1. function fn(a) {
  2. console.log(a) //function() {}
  3. var a = 123
  4. console.log(a) //123
  5. function a() {}
  6. console.log(a) //123
  7. var b = function() {}
  8. console.log(b) //function () {}
  9. function d() {}
  10. }
  11. fn(1)


  1. 创建 AO 对象 Activation Object(执行期上下文,作用是理解的作用域,函数产生 的执行空间库)
  2. 找形参和变量声明,将变量和形参名作为 AO 属性名,值为 undefined

    1. AO{
    2. a : undefined,
    3. b : undefined
    4. }
  3. 将实参值和形参统一(把实参值传到形参里)

    1. AO{
    2. a : 1,
    3. b : undefined
    4. }
  4. 在函数体里面找函数声明,提升函数声明并将函数体赋予函数名,function a () {}和 function d () {}都是函数声明,但是 var b = function (){}不是声明而是函数表达式所以不提升,a函数提升覆盖了形参的值

    1. AO{
    2. a : function a() {},
    3. b : undefined,
    4. d : function d() {}
    5. }
  5. 执行第一行 console.log(a);时,用的是

    1. AO{
    2. a : function a() {},
    3. b : undefined,
    4. d : function d() {}
    5. }
  6. 执行 var a =123;改变的是

    1. AO{
    2. a : 123,
    3. b : undefined,
    4. d : function d() {}
    5. }
  7. 在 b = function (){}时

    1. AO{
    2. a : 123,
    3. b : function () {},
    4. d : function d() {}
    5. }
  1. function test() {
  2. var a = 123
  3. function a() {}
  4. console.log(a) //123
  5. }
  6. test()
  7. AO{
  8. a : undefined
  9. }
  10. AO{
  11. a : function a() {}
  12. }
  13. //-----------预编译结束
  14. var a = 123
  15. AO{
  16. a : 123
  17. }
  18. function a() {} //什么都不做,因为已经做了

全局预编译

  1. 生成了一个 GO 的对象 Global Object(window 就是 GO)
  2. 找形参和变量声明,将变量和形参名作为 GO 属性名,值为 undefined
  3. 在函数体里面找函数声明,值赋予函数体,没有就新增属性
    1. console.log(a) //function a() {}
    2. var a = 123
    3. console.log(a) //123
    4. function a() {}
    image.png

    预编译例子

    先进行GO,再进行AO

image.png
image.png
image.png
image.png