博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从var func=function 和 function func()区别谈Javascript的预解析机制
阅读量:5148 次
发布时间:2019-06-13

本文共 2817 字,大约阅读时间需要 9 分钟。

var func=function 和 function func()在意义上没有任何不同,但其解释优先级不同

后者会先于同一语句级的其他语句。
即:

{ var k = xx(); function xx(){
return 5;}}

不会出错,

{ var k = xx(); var xx = function(){
return 5;}}

则会出错。

 

为什么会这样呢?这就要引出javascript中的预解析机制来解释了。

JavaScript解析过程分为两个阶段,一个是编译阶段,另外一个就是执行阶段。

  * 编译阶段

         编译阶段就是我们常说的JavaScript预解析(预处理)阶段,在这个阶段JavaScript解释器将完成把JavaScript脚本代码转换到字节码。

  * 执行阶段

    在编译阶段JavaScript解释器借助执行环境把字节码生成机械码,并顺序执行。

 

编译阶段(预解析阶段)做什么操作?

  * var , function声明的变量提升

    首先,创建一个当前执行环境下的活动对象,然后将用 var 声明的变量设置为活动对象的属性(也就是将其添加到活动对象当中)并将其赋值为undefined,然后将function 定义的函数 也添加到活动对象当中。

1 if( false ){2     var aa = 20;3     var bb = 30;4 }5 6 function AA(){};7 function BB(){};8 9 //var定义的aa,bb以及function定义的AA(),BB()都会被变量提升到window对象下面

 

    * 函数声明与函数表达式在预解析的区别

    首先,我们知道解析器会对function定义的函数(也就是函数声明)在代码开始执行之前对其实行函数声明提升(function declaration hoisting),所以在函数声明之前调用该函数是不会在执行期间报错,但是函数表达式不同,函数表达式用 var 声明,也就是说解析器会对其变量提升,并对其赋值为undefined,然后在执行期间,等到执行到该var 变量的时候再将其变量指向一个function函数,所以在函数表达式之前执行该函数是会报错的。

1 AA();2 function AA(){};3 4 BB();5 var BB = function(){};6 7 //AA();不会报错,因为是以function的变量提升,BB()会报错,因为是以var的变量提升,到其相当于 BB(); var BB = undefined; BB = function(){};

 

  * function 覆盖

    若定义了两个同名的函数,则在预解析期间后面一个会覆盖签名一个

1 AA();   // 输出 I am AA_2;2 function AA(){3    console.log('I am AA_1');4 };5 6 AA();  // 输出 I am AA_2;7 function AA(){8   console.log('I am AA_2');9 }

 

  * 预解析把变量或函数解析到其运行时的环境中

    解析器将变量提升并不是将所有的变量都提升到window对象下面,其提升的原则是提升到变量运行的环境中去。

1 aa = "I am aa"; 2 (function(){ 3     console.log(aa);  // 输出 aa 是 undefined 4     var aa = "I am aa in a function"; 5     console.log(aa);  //输出 aa 是 I am aa in a function 6 })(); 7  8 // 这里 aa 被变量提升,但是aa 没有被变量提升到 window下面,而是被提升到其运行的环境 (function(){ })() 中去,也就是等同于 9 10 // aa =  "I am aa";11 //(function(){12 //    var aa;  13 //    console.log(aa);  // 输出 aa 是 undefined14 //    aa = "I am aa in a function";15 //    console.log(aa);  //输出 aa 是 I am aa in a function16 //})();17 18 19 20 // 下面代码等同于上面,目的是为了若看不懂上面,则可看下面。21 aa = "I am aa";22 function AA(){23     console.log(aa);24     var aa = "I am aa in a function";25     console.log(aa);26 }27 AA();

 

  * JavaScript“预解析”分段进行

    所谓分段进行是按照<script>标签来分块进行预解析

1 11 12 13 18 19 //上面例子说明function函数声明是分块的,然而至于var变量的提升经过反复验证是不分块的( 此处如有不同意见请指教 )。

 

  * var 变量提升以及 function 函数声明提升

    该点是对函数声明以及函数表达式进一步的说明,其实前面函数声明和函数表达式在预解析的不同表现,其主要的原因就是 var 和 function 两者不同的提升。这个问题从解析阶段到运行阶段来说明。首先,在解析阶段 var 后面的 AA 会被提升然后 AA 被定义为undefined,BB 也会被提升,而BB被提升后的内容就是整个 function 里面的内容,其实从浏览器的控制台我们可以看出一二。然后,整个解析过程完了就到了运行阶段,在运行阶段期间,当读到 AA() 的时候,其实就是将 AA 这个变量指向function(){}这个函数然后调用,而到了 BB() 的时候,就会从之前声明的函数中去查找该早已经声明的函数,然后直接调用。

1 var AA = function(){ 2    console.log(' AA_ 1 '); 3 } 4  5 AA(); // 输出 AA_1 6  7  8 function AA(){ 9    console.log(' AA_2 ');10 }11 AA(); //输出 AA_212 13 //这个例子就很好说明了 var 在运行阶段动态内建,而 function 在预解析阶段静态建立。

转载于:https://www.cnblogs.com/shytong/p/5100426.html

你可能感兴趣的文章
box-sizing
查看>>
【每天学点Python】案例七:模拟掷骰子
查看>>
Python进阶:生成器
查看>>
K大数查询(bzoj 3110)
查看>>
皇家马德里都在用的云服务,究竟是什么样的?
查看>>
Azure 门户中基于角色的访问控制入门
查看>>
立即执行函数表达式
查看>>
dp练习(9)——最大乘积
查看>>
上传文件的大小
查看>>
本地模拟服务器CDN(静态HTML,CSS,JS)开发
查看>>
linux学习一
查看>>
Codeforces Round #484 (Div. 2)
查看>>
「北京」京东 JD.COM 招聘中/高级前端工程师
查看>>
Block Towers (思维实现)
查看>>
0911,练习题
查看>>
T- SQL性能优化详解
查看>>
javascript 操作 cookie 【转】
查看>>
数据库设计
查看>>
apicloud模块开发知识点
查看>>
C#3.0 语言基础扩充
查看>>