JS提升(hoisting)详解

本文围绕JS解析机制展开,介绍其解析分编译和执行两阶段。编译阶段会对变量和函数预处理,hoisting在此发生,有函数优先等提升原则;执行阶段将字节码生成机械码执行。JS按块执行,块间变量和函数可共享,可借助事件机制改变执行顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近期在学习js,了解到js的一个名词,就是hoisting,进而了解了下js的解析机制

详情可参考:http://www.runoob.com/js/js-hoisting.html

js的解析过程分为两个阶段:编译阶段和执行阶段

编译阶段:即我们常说的预处理阶段,javascript解析器把js脚本代码转换为字节码

在这个阶段,解析器所做的事有:

将所有变量和函数进行预处理hoisting就是在这个时候发生的。

提升原则:

1.函数优先于变量即函数提升完之后,才会处理变量的声明,

2.对于已经初始化的变量(var a=2;)是不会提升的,

3.使用表达式定义函数(eg:var a =function(){console.log();})是无法提升的。

例如:

<script>
function func(){  //函数声明和函数表达式的区别
	alert(" a:"+a());
	alert("b="+b);
	var a=1;
	var b;
	b=2;
	alert("b="+b);
	function a()
	{
		alert("this is function a");
		return "this is a return a";
	}
	alert( "a:"+a);           
}
func();
</script>
//输出结果:
this is function a
a:this is a return a
b=undefined
b=2
a=1

提升(hoisting)后:

<script>
function func(){  //函数声明和函数表达式的区别
	function a()//函数声明提升
	{
		alert("this is function a");
		return "this is a return a";
	}
	var b;//未初始化的变量,提升,后于函数
	alert(" a:"+a());
	alert("b="+b);
	var a=1;//对于已经初始化的变量,则不提升
	b=2;
	alert("b="+b);
	alert( "a:"+a);           
}
func();
</script>

函数的提升:

<script>
	try
	{
		
		a();
		function a()
		{
			alert("this is function a");
		}
		alert(b);
		b();//出错位置
		var b=function(){
			alert("this is function b");
		}
		b();
	}catch(e)
	{
		alert(e);
	}
</script>
//输出结果
//this is a function a
//undefined
//TypeError: b is not a function



//提升之后的结果:
<script>
	try
	{
        function a()//常规函数提升
		{
			alert("this is function a");
		}
        var b;//表达式函数提升

		a();
		alert(b);//b未定义
		b();//b未定义,不是函数,报错
		b=function(){
			alert("this is function b");
		}//变量定义
		b();
	}catch(e)
	{
		alert(e);
	}
</script>

执行阶段:将字节码生成机械码并按顺序执行。

JS代码是按块被引擎预编译和解释执行的,所谓块就是<script>标签分割的代码段。

注意:JS是按块被引擎预编译和解释执行的,一对<script></script>标签表示一个执行块,因此在当前块中调用下一个块中声明定义的变量和函数会报语法错误。

虽然js是按照块执行的,但是因为所有块同属于同一个全局作用域,即块之间的变量和函数是可以共享的。

因此我们可以借助事件机制,来改变执行顺序。

当文档流完全被加载完毕,再次访问就不会出现语法错误,比如将访问第二个代码块中的变量和函数的代码放在页面初始化事件函数中,就不会提示语法错误。、
  

<script>
    window.onload = function() { //页面初始化(加载)完毕之后才执行页面初始化事件处理函数
        alert(a);
        f();
    }
</script>
    
<script>
        var a = 1;
        function f() {
            alert(a+a);
        }
</script>


    //除了页面初始化事件外,还可以通过各种交互事件如鼠标事件、键盘事件、时钟触发等改变JS代码执行顺序

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值