深刻理解javascript引擎对于脚本的处理

脚本处理模型

javascript的基本特色


  1. js是一门至关简单的运行时解释语言。javascript

  2. 对象模型很直接也没有类的概念。html

  3. 有自动垃圾回收。java

  4. 弱数据类型。编程

  5. 动态类型(dynamic typing):运行的时候才肯定对象的类型。浏览器

  6. javascript没有内置的I/O机制。框架

扩展:javascript程序与宿主环境进行交互,是经过一系列预约义的方法和属性实现的,这些方法和属性会再映射成浏览器的内部原生代码,因此与其余很对常规的编程语言不一样,浏览器开放的这些借口每每受限且有针对性。编程语言

脚本处理模型

首先,不管是独立的窗口仍是在框架里面,每一个展现在浏览器里面的html文档,都被赋予了一个独立的javascript执行环境实例,在这个环境里面加载的脚本的全部全局变量和函数都拥有一个独立的命名空间。函数

而后,同一个文档的全部脚本都运行在同一个执行环境里面,共享同一个沙箱,而且可以经过浏览器提供的API与其余上下文环境交互。spa

最后:在特定的执行上下文里面,每段javascript代码块都是自成体系处理的,顺序也基本肯定。每段代码块都是由若干符合语法格式的独立单元组成,处理的过程包括清晰并且连续的三个步骤:源码处理,函数解析,代码执行。命令行

源码处理

源码处理阶段会检查脚本代码块里面的语法,一般会先把代码转换成中间层的二进制映像,这样才能或获得使人满意的执行速度。在完全完成这一步骤以前,这些二进制代码对全局并没有影响。若是源码处理阶段出错,整个有问题的代码块都会被弃用;而后解析器会继续处理下一段代码块。

函数解析

完成了上一步骤以后,接下来就是解析器对当前代码块里全部具名的全局函数进行识别并注册。在这一阶段完成以后,这些函数才能被执行代码所调用。

对于代码

<script>
hello_world();

function hello_world(){
    console.log('hello, man');
}
</script>



由于javascript在执行前会额外预处理,所以上面的写法会成功执行。

而对于代码

<script>
hello_world();
</script>

<script>
function hello_world(){
    console.log('hello, man');
}
</script>



对于这段代码会由于运行的时候错误而执行失败,由于代码里每段独立的代码块并非同时处理的,这是根据javascript引擎读取代码块的前后顺序决定的。在执行第一个代码块的时候,定义hello_world()的那块代码块尚未被解析呢。

再看代码

<script>
hello_world();

var hello_world = function(){
    console.log('hello, men');
}
</script>



出现这个现象的缘由是:在调用hello_world()的时候,对于hello_world变量的赋值尚未开始呢!

解释:javascript这种全局名称解析模型只针对于函数有效,而对于变量的声明却并不是如此。与其余脚本语言相似,变量是按照执行的时候出现的顺序注册的。

代码执行

一旦函数解析阶段也执行完毕了,javascript引擎就会开始顺序执行在函数区块以外的全部代码。若是在执行过程当中,因为某些未处理的异常或者一些偏门的缘由,脚本的执行可能会失败。若是碰上了这个错误,那些已经被正确解析的函数仍然能被调用,而已经执行过的代码的结果,对此上下文环境也仍然有效的。

<script>
function no_called(){
  console.log('这个函数不会被执行,由于没有被调用到!');
}

function hello_world(){
  console.log('这个函数只有在被调用到的时候才会被执行。效果是在命令行中出现这句话,而后抛出一个异常:由于调用了一个没法解析的函数');
  do_stuff();
}

console.log('整个程序会从这行代码开始执行!');

hello_world();

console.log('这行代码不会被执行到,由于hello_world()会触发一个未处理的异常。');
</script>

<script>
  console.log('以前的异常是不会影响到这行独立区块的代码的,因此可以运行。')
</script>



从中咱们能够看到:因为出现了未预期和未处理的某些异常状况,因此程序的运行会带来一些出人意外的后果:此时整个应用的状态会变得不太统一,实际上即便有异常,代码也仍然有可能继续执行。

异常的本意是阻止未能预期的错误,不会再扩大这种错误的影响,因此javascript这样的设计颇为古怪。

相关文章
相关标签/搜索