一、JS的概念
JavaScript ( JS ) 是一种具有函数优先的轻量级解释型或即时编译型的编程语言。
二、JS语言特点
2.1 单线程
(1)JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率。
(2)JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
2.2 解释型语言
(1)解释一行,执行一行;不通篇编译为一个文件再执行。
三、 JS执行过程
3.1 语法分析
通篇扫描低级语法错误,但不执行。
3.2 预编译
3.3 解释执行
四、JS的预编译
(1)预编译,简单理解,就是在内存中开辟一块空间,用来存放变量和函数。
(2)预编译发生在函数执行前;也就是说函数执行时,预编译已经结束。
4.1 变量 声明提升
变量声明语句放到最前,赋值不变。
JavaScript的函数作用域是指在函数内声明的所有变量在函数体内始终是有定义的,也就是说变量在声明之前已经可用, 所有这种特性称为声明提前(hoisting),即JavaScript函数里的所有声明(只是声明,但不涉及赋值)都被提前到函数体的顶部,而变量赋值操作留在原来的位置。
(1)JavaScript 脚本在执行之前先进行预编译,所以 ① 和 ③ 不会执行,而是先执行 ②,进行预编译;
(2)因为预编译阶段是不对变量进行赋值的,即不进行初始化,所以 ② 也只执行前半部分 var a
,由于只声明了变量,而没有进行赋值,所以此时变量的值为 undefined;
(3)预编译完毕之后,JavaScript 脚本开始执行,执行顺序按照从上到下的顺序执行。
4.2 函数声明整体提升
函数声明语句将会被提升到外部脚本或者外部函数作用域的顶部。
(1)其实函数声明 function test() {}
已经提升到 test()
之前,这也是预编译导致的,所以函数 test()
能够在定义之前执行,并且没有报错。
五、总结
(1)理解预编译需要明白 ①变量/函数声明 和 ②变量赋值。
(2)预编译阶段,只进行 变量/函数声明,不会进行变量的初始化(即变量赋值,所有变量的值都是 undefined);变量赋值 是在解释执行阶段才进行的。
参考文章 JavaScript的预编译
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。