乐趣区

关于html:HTML的解析

1、解析规定:

1、html 字符串被浏览器接管后一句一句读取并解析
2、如果解析到 link 标签,便发送申请获取 css;
3、解析到 script 标签,发送申请获取 js 后并执行相应的代码
4、解析到 img 后会申请图片资源
5、在解析 html 过程中构建 dom 树,解析 css 等过程中构建渲染树,递归布局后进行页面绘制

2、开始解析 html

// 解析器通常会把工作调配给两个组件:分词程序负责把输出的 html 切分成非法的序列;解析程序依照句法规定去剖析而后构建句法树。
<html>

<body>
    <p>hello taya</p>
    <div><p>hiiiiii</p></div>
</body>

</html>
1
2
3
4
5
6
7
该 html 解析成 DOM 树后为:

HTMLHtmlElement
HTMLBodyElement
HTMLParagraphElement
Text
HTMLDivElement
HTMLParagraphElement
Text
3、css 选择器的读取程序是从右向左、选择器性能解释

taya div.ty span{color:red}

1
它的读取程序是:span => div class:ty => id:taya
先找到全局的 span,而后从第一个开始向上寻找 class 为 ty 的 div,而后再寻找 id 为 taya 的元素,如果没有匹配项则放弃本条门路,从下一个 span 开始寻找。
如果是自左向右,便变成了深度遍历并随同着大量的回溯节点,十分耗费性能
这也是为什么在性能方面:id 选择器 > 类选择器 > 元素选择器

4、js 解析

1、js 是单线程,只能依照先后顺序执行
2、浏览器解析是异步的,当须要申请内部资源时是不会影响 html 加载的,然而如果遇到 js 文件,则会将解析挂起,因为 js 中可能会有针对 DOM 的操作(js 优化咱们须要尽可能地去防止)
3、js 解析器会先进行预解析,即找到所有的变量、函数等进行初始化赋值为 undefined,把函数取出来成为一个函数块,寄存到仓库中,而后再解析 js 代码,和仓库进行匹配

依据以上的机制,能解释很多词法作用域的问题:

1:
console.log(a)
let a = 1
console.log(a)
// 后果:undefined 1

2: // 如果应用 let,这个例子就没有用了,会报错。
console.log(taya) //function taya(){console.log(“4”)}
var taya = “sdsd”
console.log(taya) //sdsd
function taya(){console.log(“11”)}
console.log(taya) //sdsd
var taya = “3”
console.log(taya) //3
function taya(){console.log(“4”)}
console.log(taya) //3
解析:在 js 预解析时,如果变量和函数重名,只会保留函数块,所以第一个 taya 输入为函数
在解析时,只有 + – * / % = 等字符时能力更改仓库中的值,所以后续的 taya 输入不为函数了

3:
var a = 1;
function fc(){

console.log(a)
a = 2

}
fc()
console.log(a)
输入:1 2
解析:执行 fc()函数时,发现外部并没有定义任何变量,第一行输入 a,仓库内是空的,便向内部寻找,找到了全局变量 a。

4:
var a = 1;
function fc(a){

console.log(a)
a = 2

}
fc(1)
console.log(a)
// 输入:1 1

退出移动版