上图便是我理解的js知识结构,下面先从浏览器运行原理说起:
- 浏览器载入html文件,每解析到一个标签,便将其加入DOM树中;
- 解析head时,如果遇到link、script标签(js会先处理一遍,遇到ready、onload则押后执行)便开始下载相关文件,同时继续向下解析;
- 然后到body,如果遇到script标签,则阻塞dom的解析,执行完script中的内容后再继续;
- 生成DOM树;
- 如果有类似于jQuery的ready方法的话,那么就是在此时执行的;
- 开始reflow,如果遇到img标签,则下载相关的图片流,同时继续向下解析(也就是说先在图片加载前reflow一次,图片加载完成后回过来再relow),以下任何影响到布局结构的操作都会导致reflow:
1、通过js使DOM方面修改的;
2、display,width,height,line-height等导致宽高变化的;
3、css样式的增删;
4、伪类样式;
5、在窗口变化时,与之相关的(offsetHeight,offsetWight,screen)
6、表单标签中输入值;
7、改变字体
8、接下来是repaint,添上与布局无关的修饰(color、background、visibility等);
下面是js行过程:
- 首先会有个函数调用栈(最底层的是全局上下文);
- 遇到一段函数,生成该函数的执行上下文,并将其压入栈中;
- 【执行上下文】确定arguments、prototype等(也许这个步骤再具体浏览器中是放在下一步骤中的,但是我还是觉得放这里更好理解,因为这些属性是不会随函数内部操作变化的);
- 【执行上下文】对其中的内容做一次预编译(js虽然是解释型的,但是还会对函数部分进行一次编译操作);
- 【执行上下文】根据预编译的结果 >> 变量对象VO(包含arguments);
- 步骤2-5算是创建阶段,现在则是函数的执行阶段,这时变量对象VO会转为活跃对象AO >> 生成作用域链:【执行上下文】根据当前AO对象(如果没有也可以) + 父环境VO中其他变量 >> 该执行上下文的作用域链, 同时确定this的指向。
- 最后是函数内的操作,这里面涉及的东西很多,当然也有一些方法会影响函数的创建(然后又回到了步骤2...),比如call、apply等,这些就在之后的篇幅里介绍吧。