JavaScript中的预解析详解

预解析

预解析:也叫变量提升,就是在当前作用域下,js运行之前,js的解释器会把带有var和function关键字的事先声明,并在内存中安排好。然后再从上到下执行js语句。

预解析只会发生在通过var定义的变量和function上。

通过var关键字定义的变量进行预解析的时候:只要是通过var定义的,不管是变量,还是函数,都是先赋值undefined,如果是变量,也不管变量有没有赋值,在预解析阶段,都是会被赋值为undefined。

<script>
   console.log(a); //打印 undefined 
   var a = 1;
   console.log(b); //打印 undefined 
   var b = function() {
       console.log(c); //打印 undefined 
   };
   b();
   var c;
</script>

function进行预解析的时候,不仅是声明而且还定义了,但是它存储的数据的那个空间里面存储的是代码是字符串,没有任何意义。

 <script>
    console.log(a); //打印的是下面的function函数体
    function a() {
       console.log("预解析function");
    }
</script>

​ 预解析是发生在当前作用域下的,刚开始的时候,我们预解析的是全局作用域,在js中我们的global就是我们的window。 我们运行函数的时候会生成一个新的私有作用域(每次执行都是新的,执行完成就销毁)这个作用域下我们可以理解为开辟了一个新的内存空间。在这个内存中我们也要执行预解析。当我们的函数执行完成后,这个内存或者作用域就会销毁 如果在当前作用域下的一个变量没有预解析,就会向它的上一级去找,直到找到window,如果window下也没有定义,就会报错。所以,在函数内通过var定义的变量是局部变量,没有能过var 定义的变量是全局变量。 预解析不会在同一个变量上重复的发生,也就是一个变量如果已经在当前作用域下预解析了,不会再重复解析。

特别注意:在预解析的过程中,函数声明比变量声明优先

  • 案例一
<script>
    //函数声明在变量声明前面,所以打印的是函数a
    console.log(a); //打印 a函数的函数体
    var a = 10;

    function a() {
       var b = 20;
       console.log(b);
    }
</script>
//模拟预解析过程
//<script>
    //变量和函数会提升,函数会优先于变量
	//function a(){
		//在函数内部也会进行预解析过程
		//var b;
		//b = 20;
		//console.log(b);
      }
    //var a;
    //-----------------------------------以上是js预解析的过程,此过程不会执行代码,只是在内存中开辟了相应的空间,并且会给变量a赋值为undefined,如果是定义的函数表达式,也会被赋值为undefined
    //-------------------------js预解析过后,然后按照顺序执行代码
    //console.log(a);
    //a = 10;  
//</script>
  • 案例二
<script>
   console.log(a); //打印a函数的函数体
   console.log(a()); //打印结果为undefined
   var a = 10;
   function a() {
       console.log(20); //打印20
   }
   console.log(a); //打印10
   a = 50;
   console.log(a()); //报错
</script>
//模拟预解析过程
<script>
    //变量和函数会提升,函数会优先于变量
	//function a(){
		//console.log(20);
      }
    //var a;
    //-----------------------------------以上是js预解析的过程,此过程不会执行代码,只是在内存中开辟了相应的空间,并且会给变量a赋值为undefined,如果是定义的函数表达式,也会被赋值为undefined
    //-------------------------js预解析过后,然后按照顺序执行代码
    //console.log(a);打印的是a函数的函数体
    //console.log(a());首先会执行a函数,括号中是函数的调用,会打印20。由于a函数中没有返回值,函数会默认返回一个undefined,所以会打印undefined。
    //a = 10; 
    //console.log(a); //此时a已经被赋值为10,所以打印的是10.
    //a = 50;
    //console.log(a()); //此时a已经被赋值为50,a已经不是函数了,再调用就会报错,也就不会被执行。就算a不被赋值为50,执行此行代码也会被报错,因为在前面a的值已经被赋值为10,就已经不是函数了。
</script>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值