javascript -- 预编译

js特点:

  • 解释性语言
  • 单线程

js执行过程

-语法分析

语法分析就是JavaScript在执行文档之前会进行一个语法的分析,通俗的意思就是先大概扫描一遍,看看有没有犯最低级的语法错误,如果有,那就报错。


错误正常分两种:
- 语法错误(低级错误)
- 逻辑错误(正常错误)


- 预编译
  • 函数声明,整体提升
  • 变量,声明提升
//函数
test();

function test(){
console.log(a);
}
//这样的函数能正确执行,原因是因为函数整体提升了,函数永远在逻辑的最前面,所以无论你在哪里执行,无所谓
//变量
console.log(a);
var a = 123;

//这样的变量不能正确执行,会提示undefined,因为变量提升了,但是变量提升的时候,值并不会跟着提升。如下:

var a;
console.log(a);
a = 123;

预编译前奏

  • 列表内容inply global 暗示全局变量 : 即任何变量未经声明就赋值,此变量就为全局变量(window)所有.
// 例如
a = 123;//这个就是全局变量所有的

var a = b = 123;//解释如下
//自右向左执行
var a = b  b = 123;
//这样子做有个缺陷,会产生一种结果,a是声明的变量,而b是window的未声明的变量
var a = b = 123;
var a. b = 123, a = b
//在function里面执行的结果
fucntion test(){
    var a = b =123;
}
console.log(window.a);//undefined
console.log(window.b);//123;
//原因是,a属于test的域里面,而且声明了,不归window所有,而b是没有声明的变量,所以是window所有
  • 一切声明的全局变量,都是window的属性
    var a = 123 ===> window.a = 123;

  • window是什么呢?
    window就是一个仓库,就是一个全局的域,window也是一个对象
    window就是全局

var a = 123;
var b = 456;
var c = 789;
//因为所有的声明的全局变量都是window的属性,所以可以理解为:

window{
    a:123;
    b:456;
    c:789;
} //因为window是对象!对象!对象! 
console.log(a) ==> console.log(window.a)   //相等

只要是全局的,全都是window的

预编译四部曲

题目:

<script>
   function fn(a) {
       console.log(a);
       var a = 123;
       console.log(a);
       function a() {}
       console.log(a);
       var b = function () {}
       console.log(b);
       function d() {}
   }
   fn(1);
</script>

- 创建AO对象(activation Object)

AO{

}

- 找形参和变量声明,将变量和形参名作为AO属性名,值为 undefined

AO{
    a:undefined,
    b:undefined,
}

- 将实参值和形参值统一

AO{
    a:1,
    b:undefined,
}

- 在函数体里面找函数声明,值赋予函数体

AO{
    a:function a (){},
    b:undefined,
    d:function d (){},
}

最后进行执行

首先一句一句执行,执行第一句console.log(a);那么,会在Ao对象中调取a,
在ao对象中a等于function a(){},那么就输出function a(){},然后到达第二句,
var a = 123,var a 已经被提升了,所以不用管,直接到a = 123,所以,在
Ao对象中,a变成了123

AO{
    a:123,
    b:undefined,
    d:function d (){},
}

AO对象变成123后,再来进行执行第三句,console.log(a);那么,现在a等于123,那么就是输出123,
到达第四句,第四句是函数,由于函数已经被提升了,所以没有这一步,然后再到第五句,第五句是console.(a),所以输出还是123吧,然后再到第六句,第六句是var b = function (){},所以就要把在AO对象中的b的属性改为function(){}

```
AO{
    a:123,
    b:function(){},
    d:function d (){},
}

所以在第七句b的输出就是function(){},第八句直接被提升了,所以不用读了。总提答案为:

function a(){}
123
123
function(){}

注意点:预编译发生在函数执行的前一刻

预编译练习题
<script>
    function test(a,b) {
        console.log(a);
        c = 0;
        var c ;
        a = 3;
        b = 2;
        console.log(b);
        function b() {}
        function d() {}
        console.log(b);
    }
    test(1);
</script>

答案解释

//1.创建AO对象
AO {

}
//2.找形参和变量声明,将变量和形参名作为AO属性名,值为 undefined
AO{
    a:undefined,    //形参声明
    b:undefined,    //形参声明
    c:undefined,    //变量声明
}
//3.将实参值和形参值统一
AO{
    a:1,            //因为a的实参为1,所以为1
    b:2,            //因为b的值为2
    c:0,            //因为c的值为0
}
//4.在函数体里面找函数声明,值赋予函数体
AO{
    a:1,                  //因为a的实参为1,所以为1
    b:function d(){} ,    //因为b有函数体
    c:0,                  //因为c的值为0
    d:function d(){}      //因为d有函数体
}
最后进行执行,从第一句读下来,答案如下:
1. a == 1
2. c == 0
3. var c 因为提升了,所以不用读
4. a == 3
5. b == 2
6. b == 2
7.因为提升了,所以不用读
8.因为提升了,所以不用读
9. b == 2

最后答案为   1 2 2 
预编译练习题2
<script>
    function test(a,b) {
        console.log(a);     //只要有函数表达式,那么肯定是函数表达式  function(){}
        console.log(b);     //undefined
        var b = 234;
        console.log(b);     //234
        a = 123;
        console.log(a);     //123
        function a (){}    //函数声明
        var a;
        b = 234;            
        var b = function () {}; //函数表达式
        console.log(a);     //123
        console.log(b);     //function(){}
    }
    test(1);
</script>

预编译分两个,第一个是全局的预编译,第二个是函数的预编译

全局的预编译如下:
  1. 创建GO对象(Global Object) GO也就是window
  2. 找形参和变量声明,将变量和形参名作为AO属性名,值为 undefined
  3. 在函数体里面找函数声明,值赋予函数体
函数的预编译如下:
  1. 创建AO对象
  2. 找形参和变量声明,将变量和形参名作为AO属性名,值为 undefined
  3. 将实参值和形参值统一
  4. 在函数体里面找函数声明,值赋予函数体

注意点:如果没有声明的变量,系统会放到GO去预编译的。

function test(){
    var a = b = 123;
    console.log(window.a)  //undefined
    console.log(window.b)  //123
}
 /*
AO{
    a : 123;
}

GO{
    b : 123;
}
*/ 

全局加函数预编译练习题
<script>
    function test() {
        console.log(b);     //undefined
        if (a) {
            var b = 100;
        }
        c = 234;
        console.log(c);     //234
    }
    var a;
    test();
    a = 10;
    console.log(c);         //234

   /* GO{
        test:undefined,
        c:234,
        a:undefined
    }

    AO{
        b = undefined
    }*/
</script>

baidu 2013 面试题

//1.
function bar() {
        return foo;
        foo = 10;
        function foo() {

        }
        var foo = 11;
    }
    console.log(bar());
//2.
console.log(bar());
    function bar() {
        foo = 10;    
        function foo() {
        }
        var foo = 11;
        return foo;
    }
- 解释执行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值