1,预解析的过程。
2,代码的执行过程。
预解析:程序在执行过程,会先将代码读取到内存中检查,会将所有的声明在此处进行标记,所谓的标记就是让js解析器知道这个名字,后面在使用这个名字的时候,不会出现未定义的错误,‘这个标记过程就是提升。
## 声明:
1,名字的声明,标识符的声明(变量的声明)
** 名字的声明就是让我们的解析器知道这个名字
** 名字并没有任何数据与之对应
2,函数的声明
** 函数声明包括两部分
** 函数声明与函数表达式的区别,函数声明是单独写在一个结构里面的,不存在任何语句,逻辑判断结构中
注:针对函数声明和函数表达式。新旧浏览器不一样。
### 又如下面的预解析执行过程
function f() {};
** 首先告诉解析器有这个函数名字的存在,该阶段与变量的名字声明一致
** 然后告诉解析器这个名字连接的函数体
### 下面代码的解析执行过程
报错:numb is not a function
分析过程:
1,预解析代码,提升名字
***首先提升名字 numb
***再提升函数名,但是 numb 已经存在,使用跳过,让名字与函数体对应
***预解析后只有一个名字 numb
2,开始执行代码,从第一句赋值语句开始
***numb 赋值为1
***覆盖了函数体
3,调用numb,由于numb是数字1,因此保错
*****************************************************************************************************************
执行结果:1,undefined
2,456
代码解析与执行过程:
、
***************************************************************************************************************************************************************
4,JavaScript单线程处理代码与事件过程
虽然JavaScript是单线程的,可是浏览器内部不是单线程的。你的一些I/O操作、定时器的计时和事件监听(click, keydown…)等都是由浏览器提供的其他线程来完成的。
如果想利用多线程处理一些耗时较长的任务,可以使用HTML5提出的Web Worker。
二、任务队列和事件循环
JS 是单线程的,但是却能执行异步任务,这主要是因为 JS 中存在事件循环(Event Loop)和任务队列(Task Queue)。
事件循环:JS 会创建一个类似于 while (true) 的循环,每执行一次循环体的过程称之为 Tick。每次 Tick 的过程就是查看是否有待处理事件,如果有则取出相关事件及回调函数放入执行栈中由主线程执行。待处理的事件会存储在一个任务队列中,也就是每次 Tick 会查看任务队列中是否有需要执行的任务。
任务队列:异步操作会将相关回调添加到任务队列中。而不同的异步操作添加到任务队列的时机也不同,如 onclick, setTimeout, ajax 处理的方式都不同,这些异步操作是由浏览器内核的 webcore 来执行的,webcore 包含上图中的3种 webAPI,分别是 DOM Binding、network、timer模块。
onclick 由浏览器内核的 DOM Binding 模块来处理,当事件触发的时候,回调函数会立即添加到任务队列中。
setTimeout 会由浏览器内核的 timer 模块来进行延时处理,当时间到达的时候,才会将回调函数添加到任务队列中。
ajax 则会由浏览器内核的 network 模块来处理,在网络请求完成返回之后,才将回调添加到任务队列中。
主线程:JS 只有一个线程,称之为主线程。而事件循环是主线程中执行栈里的代码执行完毕之后,才开始执行的。所以,主线程中要执行的代码时间过长,会阻塞事件循环的执行,也就会阻塞异步操作的执行。只有当主线程中执行栈为空的时候(即同步代码执行完后),才会进行事件循环来观察要执行的事件回调,当事件循环检测到任务队列中有事件就取出相关回调放入执行栈中由主线程执行。
------此部分转载自v客学院吧的wrx3166
-------转载目的方便自己阅读
注:个人学习笔记