JavaScript预解析

JavaScript预解析

一、预解析

  在理解 JS 的预解析前,我们先来看几个简单的代码程序,看看都会出现什么结果。

代码一:没有声明 num 变量,直接在控制台打印 num 变量。

<script>
  console.log(num);
</script>

代码二:先在控制台打印 num 变量,之后在声明并赋值。

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

代码三:先调用函数,之后在用函数关键字 function 来声明和定义函数。

<script>
  fn();
  function fn(){
  	console.log('你好');
  }
</script>

代码四:先调用函数,再用函数表达式的方法声明和定义函数。

<script>
  fun();
  var fun = function(){
  	console.log('大家好');
  }
</script>
代码执行结果

  如果能很好的理解上述的四段小程序为什么会输出相应的结果,那应该就是懂了 JS 预解析的过程。不能理解也不要紧,看完下面介绍就能完全搞懂。

  其实 JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。JavaScript 解析器在运行 JavaScript 代码的时候分为两步:预解析代码执行

  • 预解析:JS 引擎会把 JS 代码里所有的 var(变量预解析) 和 function(函数预解析) 提升到当前作用域的最前面。

  • 代码执行: 预解析后再按照代码执行的顺序从上往下执行。

二、变量预解析与函数预解析

  • 变量预解析:就是把所有的变量声明提升到当前作用域的最前面,不提升赋值操作。
<script>
  console.log(num);
  var num = 10;
	// 上面代码相当于执行了以下代码
	var num;		// 变量提升 默认值:undefined
	console.log(num);
	num = 10;
</script>

  以上是开头代码二的实际执行过程,先把 num 变量声明给提到了当前作用域前面,并没有提升赋值操作,所以默认就是 undefined 。下面是代码四的实际过程。这里就能明白代码二和代码四输出的结果啦!

<script>
  fun();
  var fun = function(){
  	console.log('大家好');
  }
  // 上面代码相当于执行了以下代码
  var fun;	// 变量提升
	fun();		// 还不是函数
	fun = function(){
  	console.log('大家好')
  }
</script>
  • 函数预解析:就是把所有的函数声明提升到当前作用域的最前面,不调用函数。
<script>
  fn();
  function fn(){
  	console.log('你好');
  }
	// 上面代码相当于执行了以下代码
	function fn(){
  	console.log('你好');
  }
	fn();
</script>

  这里要注意,函数提升提升的是用函数关键字 function 声明的函数,而像代码四中用函数表达式的方法声明不提升。

三、预解析案例分析

  • 案例一:输出结果是什么?
<script>
  var num = 10;
	fun();
	function fun(){
  	console.log(num);
    var num = 20;
  }
</script>
  • 案例二:输出结果是什么?
<script>
  var num = 10;
	function fn(){
  	console.log(num);
    var num = 20;
    console.log(num);
  }
	fn();
</script>
  • 案例三:输出结果是什么?
<script>
  var a = 18;
	f1();
	function f1(){
    var b = 9;
  	console.log(a);
    console.log(b);
    var a = '123';
  }
</script>
  • 案例四:输出结果是什么?
<script>
	f1();
	console.log(c);
  console.log(b);
  console.log(a);
	function f1(){
    var a = b = c = 9;
  	console.log(a);
    console.log(b);
    console.log(c);
  }
</script>

  有想到每个案例的结果吗?这里给出每个案例的结果,简单提下案例四里第 7 行代码 var a = b = c = 9; 相当于 var a = 9; b = 9; c = 9; bc 变量前面都没有关键字 var 所以他们是全局变量,函数外面也能够访问到。

案例一:undefined

案例二:undefined 20

案例三:undefined 9

案例四:9 9 9 9 9 报错

下面提供每个案例代码的实际流程代码。

// 案例一原代码
<script>
  var num = 10;
	fun();
	function fun(){
  	console.log(num);
    var num = 20;
  }
</script>
// 相当于以下代码
<script>
  var num;	// 变量提升 默认值:undefined
	function fun(){		// 函数提升
    var num;				// 函数内部变量提升 默认值:undefined
  	console.log(num);		// 打印就近的变量 undefined
    num = 20;
  }
	num = 10;
	fun();
</script>
// 案例二原代码
<script>
  var num = 10;
	function fn(){
  	console.log(num);
    var num = 20;
    console.log(num);
  }
	fn();
</script>
// 相当于以下代码
<script>
  var num;		// 变量提升 默认值:undefined
	function fn(){	// 函数提升
    var num;			// 函数内部变量提升 默认值:undefined
  	console.log(num);		// 打印就近的局部变量 undefined
    num = 20;			// 给函数内部变量赋值20
    console.log(num);		// 打印就近的局部变量 20
  }
	num = 10
	fn();
</script>
// 案例三原代码
<script>
  var a = 18;
	f1();
	function f1(){
    var b = 9;
  	console.log(a);
    console.log(b);
    var a = '123';
  }
</script>
// 相当于以下代码
<script>
  var a;		// 变量提升 默认值:undefined
	function f1(){		// 函数提升
    var b;					// 函数内部变量b提升 默认值:undefined
    var a;					// 函数内部变量a提升 默认值:undefined
    b = 9;					// 给函数内部变量b赋值9
  	console.log(a);	// 打印就近的局部变量a undefined
    console.log(b);	// 打印就近的局部变量b 9
    a = '123';			// 给函数内部变量a赋值'123'
  }
	a = 18;
	f1();	
</script>
// 案例四原代码
<script>
	f1();
	console.log(c);
  console.log(b);
  console.log(a);
	function f1(){
    var a = b = c = 9;
  	console.log(a);
    console.log(b);
    console.log(c);
  }
</script>
// 相当于以下代码
<script>
  function f1(){				// 函数提升	
    var a;							// 函数内部变量a提升 默认值:undefined
  	a = 9;							// 给函数内部变量a赋值9
  	b = 9;							// 定义全局变量b并赋值9,不是 var 关键字修饰不提升
  	c = 9;							// 定义全局变量c并赋值9,不是 var 关键字修饰不提升
  	console.log(a);			// 打印就近的局部变量a 9
    console.log(b);			// 打印全局变量b 9
    console.log(c);			// 打印全局变量c 9
  }
	f1();
	console.log(c);				// 函数外打印全局变量c 9
  console.log(b);				// 函数外打印全局变量b 9
	console.log(a);				// a 是函数内局部变量,函数外不能访问,报错
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ItDaChuang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值