JavaScript中的预解析

引言

让我们来看看两种函数声明方式在不同的位置调用会发生什么结果

声明式函数声明 

<script>
    //规范写法
    function foo(){
        console.log("hello world");
    }
    foo(); //hello world
</script>

如果我们将foo();提前,也可以运行。 

<script>
    foo(); //hello world
    function foo(){
        console.log("hello world");
    }
</script>

这是声明式的函数声明。可以在任何位置调用。

赋值式函数声明 

<script>
    //规范写法
    var foo = function(){
        console.log("hello world");
    }
    foo(); //hello world
</script>

而如果我们将foo();提前,会报类型错误(TypeError):foo is not a function;

<script>
        //会报错,类型错误
        foo(); 
        var foo = function(){
            console.log("hello world");
        }
</script>

再看直接foo();的时候的情况:会报引用错误(ReferenceError):foo is not defined ;

<script>
    foo(); 
</script>

 

 

不同的声明方式,不同的调用位置,会产生不同的结果。原因是什么?这就来到了我们今天要说的预解析

正文

JavaScript是一种解释型语言,就是在代码执行之前,先对代码进行通读和解释,然后再执行代码。也就是说,我们的js代码在运行的时候,会经历两个环节:解释代码(预览代码)和执行代码

预解析:

1.检查你的代码有没有语法错误

2.声明提升:把所有需要与内存进行交互的行为提前

   2.1  变量提升

   2.2  函数提升

   2.3  变量提升和函数提升两者的优先级

1.检查你的代码有没有语法错误

首先,会检查你的代码有没有语法错误,如果有语法错误,直接终止程序。换句话说,就是如果你的代码之中有语法错误,那么你的所有代码都不会执行。

如果没有语法错误,代码从上到下执行,上面的代码照样执行,即使下面的代码有引用错误等。

<script>
    console.log("hello world");
    console.log(a); //引用错误,但上一行的hello world 照样执行
</script>

当出现语法错误的时候 ,可以看到,第一行的 hello world 也不会执行。

<script>
        console.log("hello world");
        console.log(a); 
        function (){
            
        } // 函数声明中没有函数名 --- 语法错误
</script>

2.声明提升:把所有需要与内存进行交互的行为提前

(把所有的内存操作集中在一起提升代码效率)

   2.1  变量提升

   变量声明分为两个部分:  1.变量声明  (只有这个部分提升)    2. 变量赋值

<script>
        var a = 10 ;
        var b = 20 ;
</script>
<script>
        //声明提前
        var a,b;

        //在原位置,只保留赋值部分功能
        a = 10 ;
        b = 20 ;
</script>

  如上,变量声明提前,变量赋值不提前。

  再如,当将 var a = 10 ;放在后面的时候,console.log(a)的结果是 undefined;即变量声明未赋值。

<script>
        console.log(a); //undefined
        var a = 10 ;
</script>

声明提升也就可以解释我们引言中的:

<script>
        foo(); //类型错误(TypeError):foo is not a function;
        var foo = function(){
            console.log("hello world");
        }
</script>

当foo();放在前面的时候,后面的var foo;会提前,foo 为 undefined ,所以不能被调用。(只有函数可以调用,所以报类型错误。) 

所以正确写法是在下面调用

<script>
        //正确写法     
        var foo = function(){
            console.log("hello world");
        }
        foo(); //hello world
</script>

   2.2  函数提升

   函数提升是整体提升。

   所以引言中的 声明式的函数声明 在任何位置都能调用。

<script>
    foo();
    var foo = function(){
        console.log("hello world");
    }
    //foo(); //hello world
</script>

   2.3  变量提升和函数提升两者的优先级

   有一种情况:

<script>
        console.log(foo);
        var foo = 10;
        function foo(){
            
        }
</script>

   分析console.log(foo);可能会出现两种情况

   (1)undefined  ==>  表明 函数先提升,变量声明后提升

   (2)    函数       ==>  表明 变量声明先提升,函数后提升 

我们查看结果:

   结果为函数;表明 变量声明先提升 , 函数后提升 ; 即 局部提升优先提升 , 然后整体提升 。 

总结

js在预解析中,首先检查代码是否有语法错误,如果有语法错误,所有的代码都不会执行。其次,会把所有的内存操作集中在一起提升代码效率,会有声明提升。声明提升分为变量提升和函数提升,变量提升是部分提升,即只提升声明部分,而函数提升是整体提升。局部提升的优先级更高。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值