(1)编译时

编译时顾名思义就是正在编译的时候 . 那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码 .

(当然只是一般意义上这么说,实际上可能只是翻译成某个中间状态的语言.比如 Java 只有JVM识别的字节码,C#中只有CLR能识别的MSIL.另外还有啥链接器.汇编器.为了了便于理解我们可以统称为编译器)

编译时就是简单的作一些翻译工作 ,比如检查老兄你有没有粗心写错啥关键字了啊.有啥词法分析,语法分析之类的过程. 就像个老师检查学生的作文中有没有错别字和病句一样 .如果发现啥错误编译器就告诉你.如果你用微软的VS的话,点下build.那就开始编译,如果下面有errors或者warning信息,那都是编译器检查出来的.所谓这时的错误就叫编译时错误,这个过程中做的啥类型检查也就叫编译时类型检查,或静态类型检查(所谓静态嘛就是没把真把代码放内存中运行起来,而只是把代码当作文本来扫描下).

 

(2)运行时

所谓运行时就是代码跑起来了.被装载到内存中去了.

(你的代码保存在磁盘上没装入内存之前是个死家伙.只有跑到内存中才变成活的).而运行时类型检查就与前面讲的编译时类型检查(或者静态类型检查)不一样.不是简单的扫描代码.而是在内存中做些操作,做些判断.

 

(3)举例说明

java 后端判断是否微信小程序内_js编译时和运行时不同

java 后端判断是否微信小程序内_js编译时和运行时区别_02

java 后端判断是否微信小程序内_什么是编译时和运行时_03

(4)javascript的编译时和运行时

 

从它的某些表现上来看,我将其分成了“编译时”与“运行时”两个阶段,这在后面内容的理解中我认为是没有问题的。

关于“编译时”与“运行时”,要从 var关键字与 function 关键字说起。从目前我阅读到的资料和实践中只发现这两个关键字存在这样的特殊性。

var运行和编译 1.1

<script type="text/javascript">
alert(a);
var a;
</script>

这一段的执行结果与代码1.2的执行结果是一样的。不会报错,窗口提示"undefined"。即我们先前提到的那种“已声明未定义”的情况。由此,我们可以猜到 var a; 这个语句应该是在第一行语句执行之前就执行了的,“预编译”;

1.2

<script type="text/javascript">
alert(a);
var a = 1;
alert(a);
</script>

第一次仍然是提示"undefined",第二次才显示了"1"。因此,实际上只是把声明提前了,但是赋值语句仍然没有改变位置;

1.3

<script type="text/javascript">
var a;
alert(a);
a = 1;
alert(a);
</script>

我们之前提到这是var关键字的作用,现在我们来验证一下究竟是不是var关键字的作用。

1.4

<script type="text/javascript">
alert(a);
a = 1;
</script>

程序报错,也就是前文提到的“未声明”。可以看到没有使用var关键字之后,“预编译”的情况并没有出现。

function运行和编译

会看到很明显的两段时期“编译时”与“运行时”。

 

2.1

<script type="text/javascript">
func(); //2
func = function() {alert(1);};
func(); //1
function func() {alert(2);};
func(); //1
</script>

执行结果我已经标注在代码注释里了。可以看到,function关键字的“预编译”与var关键字的“预编译”稍有不同。它将其“声明”与“定义”一同“预编译”了。

2.2

<script type="text/javascript">
function func() {alert(2);};
func(); //2
func = function() {alert(1);};
func(); //1
func(); //1
</script>

也就是说,function关键字声明的函数(或者称为“类”或者“变量”我觉得都是可以的),是在“编译时”就执行了。而除了第4行代码之外,其他代码都是在“运行时”执行的,所以我们得到注释里的显示结果。

 

3.3

<script type="text/javascript">
func(); //2
func = function() {alert(1);};
func(); //1
function func() {alert(2);};
func(); //1
</script>

<script type="text/javascript">
function func() {alert(2);};
func(); //2
</script>

然而JavaScript的“预编译”并不是发生在整个页面的所有脚本中。

有人提到是按<script></script>标签“分段编译”的。

执行结果看似证明了上述的结论。第一段第4个语句明显是先于第二段第一个语句执行的。