爱客仕-前端团队博客园

浅谈虚拟DOM之词法分析器(一)

开篇词

最近这两年,如果作为一个前端程序员,要是还没听说过虚拟DOM,那基本就可以说是不合格的,但一般前端主要还是在交互,动画,数据通讯上面做一些事情,很少会涉及到编译方面的东西,虚拟DOM一听就挺虚的,就好像飘在那儿,似乎知道怎么回事,又说不出个所以然来,要是说自己实现一个,那简直可以说是无头无绪,一个偶然的机会,让我必需要面对这个问题,索性就研究了一下,并把我的感想和思路在这里分享给大家

什么叫词法分析

(以下所有名词的解释,都是我自己所理解的,可能不一定完全准确)

词法分析这个词如果是计算机专业出来的肯定不陌生,但对于其它专业的人来说,可能还是要稍加解释:

词法分析可以说,是把事先按照一定约定的字符串序列,分割成组成词法的最小单元,如: var1 + var2,就会分为三个单元,分别是var2+var2

当然,HTML没有上面的逻辑运算,但HTML的语法,大家肯定再熟悉不过了,如果我们加以归纳总结,可以说虚拟DOM就成功了一半,剩下的只是实现问题。

一段最基本的HTML代码可能如下:

1
<tag attribute="value">text content</tag>

或者是这样

1
<tag attribute="value"/>

从上面的代码,我们基本就可以看出一个HTML标签的结构了,当然,如img这样的单标签,还有<!DOCTYPE html>这样的我们先不考虑,我们用一个表格来展示:

开始标签开始 标签名 属性名 等于号 属性值 开始标签结束 文本内容 结束标签开始 标签名 结束标签结束
< tag attribute = value > text content </ tag >

下面这个其实与上面差不多,大家理解意思就行了。

为什么要词法分析

当浏览器下载了一段HTML代码的时候,其实就是一个普通字符串,只不过浏览器把它做了一次解析,然后才有我们的DOM树,包括上面的方法呀,如appendChild()parentNode……,虚拟DOM可以这么理解,就是我们用javascript去实现一次这个功能,要是能提供一个和浏览器差不多一样的API,那对使用的人来说,其实就是一个DOM,并无太大分别,然而要做这一个功能,就少不了词法分析,因为没有词法分析,我们就无法从一串看似乱七八糟的HTML字符串中间找到规律,从而组织有有序的方法来

词法分析要注意的事项

  • 词法分析不仅要分析出组成语法的各个单位,还要记录各个单位出现的位置,包括行号,从什么地方开始,到什么地方结束,当输入不规范的时候要进行提示或抛出错误
  • 空白字符也要保留记录
  • 只关注最小单元是不是符合约定的规范,并不关心其内在的逻辑是否合理,如:
    1
    2
    3
    <select>
    <a href="#"></a>
    </select>

上面这一段代码,在HTML中是不合法的,但对我们的词法分析来说,是合法的。

构建一个词法分析器类

基于第一部分的分析,我们基本已找到HTML代码的组织规范,那么我们现在可以真正的开始了:

1
2
3
4
5
6
7
8
9
10
class HtmlAST() {
ast(text) {
this.text = text;
this.length = text.length;
this.index = 0;
this.rowIndex = 0;
this.rowCharIndex = 0;
this.nodeTree = [];
}
}

我们构建了一个HtmlAST的类,AST(Abstract Syntax Tree)叫做抽象语法树,对于一般有逻辑的语言来说,其实第一步是Lexer(词法分析),但对于HTML这种没有逻辑的,可以一次生成AST,不必分成两步(这部分具体内容,可以参考编译原理)。

当调用ast方法时,传入一个html字符串,我们初始化了一些基本属性,这部分属性后面会用到。