var func=function 和 function func()在意义上没有任何不同,但其解释优先级不同:
后者会先于同一语句级的其他语句。

即:

  1. {
  2. var k = xx();
  3. function xx(){return 5;}
  4. }

不会出错,

  1. {
  2. var k = xx();
  3. var xx = function(){return 5;}
  4. }

则会出错。

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

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

  * 编译阶段

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

  * 执行阶段

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

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

  * var , function声明的变量提升

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

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

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

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

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

  * function 覆盖

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

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

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

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

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

  * JavaScript“预解析”分段进行

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

  1. 1 <script>
  2. 2 AA(); // 输出 AA2;
  3. 3 function AA(){
  4. 4 console.log('AA1');
  5. 5 }
  6. 6
  7. 7 function AA(){
  8. 8 console.log('AA2');
  9. 9 }
  10. 10 </script>
  11. 11
  12. 12
  13. 13 <script>
  14. 14 function AA(){
  15. 15 console.log('AA3');
  16. 16 }
  17. 17 </script>
  18. 18
  19. 19 //上面例子说明function函数声明是分块的,然而至于var变量的提升经过反复验证是不分块的( 此处如有不同意见请指教 )。

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

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

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

从var func=function 和 function func()区别谈Javascript的预解析机制的更多相关文章

  1. javascript中function和object的区别,以及javascript如何实现面向对象的编程思想.

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  2. function——函数声明头的提升和预解析

    函数: 即function语句的集合,就是将多个语句封装到一起: 函数的执行要会自己遍历,遇见函数 a():执行语句,就要移交控制权,函数执行完毕之后,控制权又移交回来了! 函数的参数要罗列在func ...

  3. JavaScript 中,定义函数时用 var foo = function () {} 和 function foo() {}有什么区别?

    对于新手来说(本人也是新手-_-!),好像var foo = function () {} 和 function foo(){}并没有什么区别,意识里可能就认为就是两种不同的写法而已.但是,通过网上查 ...

  4. JS里面function和Function的区别

    js里Function 与 function的不一样的,不仅仅是大小写的问题. 简单点说:大写的Function是一个类 ,而小写的function是一个对象. Function是一个构造器,func ...

  5. onclick="func()"和 onclick = "return func()"区别

    onclick="func()" 表示只会执行 func , 但是不会传回 func 中之回传值onclick = "return func()" 则是 执行 ...

  6. function foo(){}、(function(){})、(function(){}())等函数区别分析

    前面一段时间,看到(function(){}),(function(){}())这些函数就犯晕,不知道它到底是什么意思,为什么函数外要加小括号,函数后要加小括号,加和不加到底有什么区别……一直犯迷糊, ...

  7. (function ( ){})( ) 与 (function ( ){}( )) 有什么区别?

    js立即执行函数: (function ( ){})( ) 与 (function ( ){}( )) 有什么区别? 转自:http://www.jb51.net/article/75089.htm ...

  8. 闭包(Closure)和匿名函数(Anonymous function)/lambda表达式的区别

    闭包(Closure)和匿名函数(Anonymous function)/lambda表达式的区别 函数最常见的形式是具名函数(named function): function foo(){ con ...

  9. function,new function,Function,new Function 之间的区别

    测试一: var fud01 = function()  { var temp = 100; this.temp = 200; return temp + this.temp; } alert(typ ...

随机推荐

  1. 关于:Warning: skipping non-radio button in group的处理方法整理

    下面讲的是一个意思: The problem is that the next control in the tab order following the last radio button of ...

  2. 好用的下拉第三方——nicespinner

    1.简介 GitHub地址:https://github.com/arcadefire/nice-spinner Gradle中添加: allprojects { repositories { ... ...

  3. mysql快速插入大数据

    说的是插入数据,这个倒像是载入数据. 上一篇,是按照插入数据来写的,就是insert into,当时插入一万条实在是太慢了,大概是286734毫秒. insert into table values, ...

  4. HTML5、CSS3与响应式Web设计入门(1)

    HTML5与CSS3已经当仁不让的成为了这两年Web界最火爆的词,他们似乎在HTML4和CSS2统治了Web很多年之后的某一天突然爆发,然 后一直占据着所有Web开发者的视野.HTML5本身就是一个很 ...

  5. Solr中的概念:分析器(analyzer)、字符过滤器(character filter)、分词器(Tokenizer)、词元过滤器(Token Filter)、 词干化(Stemming)

    文本中包含许多文本处理步骤,比如:分词,大写转小写,词干化,同义词转化和许多的文本处理. 文本分析既用于索引时对一文本域的处理,也用于查询时查询字符串的文本处理.文本处理对搜索引擎的搜索结果有着重要的 ...

  6. Ubuntu 安装java 1.8

    1.下载java 1.8 地址: ​ http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.ht ...

  7. mongodb 连接失败

    需要加一个配置文件,mongo.config bind_ip = 127.0.0.1 dbpath = D:\MongoDB\data\db logpath = D:\MongoDB\data\mon ...

  8. ClamAV学习【9】——cvd文件解析及cli_untgz函数浏览

    这个cli_untgz函数,是用来解压CVD文件的. 那么,就刚先搞清楚CVD文件的功能作用.下了源码,我们会发现,没有前面提到的*.mdb或者*.hbd等病毒签名文件.原因就是,那些文件都是由CVD ...

  9. GO学习笔记 - 变量在定义时没有明确的初始化时会赋值为“零值 ”。

    官方教程:https://tour.go-zh.org/basics/12 变量在定义时没有明确的初始化时会赋值为 零值 . 零值是: 数值类型为 0 , 布尔类型为 false , 字符串为 &qu ...

  10. NOIP2013PUZZLE

    #include<cstdio> #include<cstring> #define MIN(A,B) (A)<(B)?(A):(B) using namespace s ...