首先,JS 是一种单线程语言,什么意思呢?从筒子里面取羽毛球的时候,只有先把上面的羽毛球取出来,才能挨个取出下面的羽毛球。JS 中的语句也要按照从上到下的顺序去执行,只有上一条语句执行完毕,才会执行下一条语句。
比如上面的代码放在浏览器中执行,肯定是按照 2,5,8 的顺序显示弹窗。但是在 JS 中有一种代码是可以被优先提取
的: 变量声明和函数声明。
先看一个之前讲过的东西:
前面讲过这两种写法,前一种方式叫做:函数声明
,后一种方式叫做:变量声明
。虽然都可以通过add()
调用,但是在 JS 执行顺序中却是大不一样。
注意看上图箭头部分,通过开发者工具,我们在watch
面板中,监控了两个变量add
和foo
,断点执行之前,你会发现add
的值已经被确定为一个函数了,foo
的值却还是一个undefined
。这是为什么呢?
在 JS 中,JS 引擎会在所有代码中优先提取所有的函数声明
和变量声明
,提前保存在内存中,便于在整段 JS 代码中调用和使用。但是这两者优先提取的过程是不同的。
函数声明
在优先提取的过程中,函数名和函数内容会被全部保存到内存中去,所以我们可以在函数声明之前调用函数。
而变量声明
在优先提取的时候,只会保存变量名,只有在执行到该语句的时候,才会被赋值。
所以如果想使用var
声明一个函数类型的变量,只能在赋值语句之后调用,赋值之前变量的值是undefined
,强制调用的话,JS 引擎会抛出一个错误,并终止运行。