ASP源码.NET源码PHP源码JSP源码JAVA源码DELPHI源码PB源码VC源码VB源码Android源码

javascript设计模式之解释器模式详解(1/23)

来源:网络整理     时间:2016-06-06     关键词:javascript设计模式

本篇文章主要介绍了"javascript设计模式之解释器模式详解",主要涉及到javascript设计模式方面的内容,对于Javascriptjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播感兴趣的同学可以参考一下: 神马是“解释器模式”?先翻开《GOF》看看Definition:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。...


神马是“解释器模式”?

先翻开《GOF》看看Definition:
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

在开篇之前还是要科普几个概念:
抽象语法树:
解释器模式并未解释如何创建一个抽象语法树。它不涉及语法分析。抽象语法树可用一个表驱动的语法分析程序来完成,也可用手写的(通常为递归下降法)语法分析程序创建,或直接client提供。

解析器:
指的是把描述客户端调用要求的表达式,经过解析,形成一个抽象语法树的程序。

解释器:
指的是解释抽象语法树,并执行每个节点对应的功能的程序。

要使用解释器模式,一个重要的前提就是要定义一套语法规则,也称为文法。不管这套文法的规则是简单还是复杂,必须要有这些规则,因为解释器模式就是按照这些规则来进行解析并执行相应的功能的。

先来看看解释器模式的结构图和说明:

javascript模式,javascript模式 pdf,javascript,高性能javascript,javascript的设计模式,javascript 单例模式,javascript观察者模式,javascript工厂模式,javascript 严格模式
AbstractExpression:定义解释器的接口,约定解释器的解释操作。
TerminalExpression:终结符解释器,用来实现语法规则中和终结符相关的操作,不再包含其他的解释器,如果用组合模式来构建抽象语法树的话,就相当于组合模式中的叶子对象,可以有多种终结符解释器。
NonterminalExpression:非终结符解释器,用来实现语法规则中非终结符相关的操作,通常一个解释器对应一个语法规则,可以包含其他的解释器,如果用组合模式来构建抽象语法树的话,就相当于组合模式中的组合对象。可以有多种非终结符解释器。
Context:上下文,通常包含各个解释器需要的数据或是公共的功能。
Client:客户端,指的是使用解释器的客户端,通常在这里将按照语言的语法做的表达式转换成为使用解释器对象描述的抽象语法树,然后调用解释操作。

下面我们通过一个xml示例来理解解释器模式:
首先要为表达式设计简单的文法,为了通用,用root表示根元素,abc等来代表元素,一个简单的xml如下:

复制代码 代码如下:



 
     
         
              12345
              d1
              d2
              d3
              d4
         

     

 

约定表达式的文法如下:
1.获取单个元素的值:从根元素开始,一直到想要获取取值的元素,元素中间用“/”分隔,根元素前不加“/”。比如,表达式“root/a/b/c”就表示获取根元素下,a元素下,b元素下,c元素的值。
2.获取单个元素的属性的值:当然是多个,要获取值的属性一定是表达式的最后一个元素的属性,在最后一个元素后面添加“.”然后再加上属性的名称。比如,表达式“root/a/b/c.name”就表示获取根元素下,a元素下,b元素下,c元素的name属性的值。
3.获取相同元素名称的值,当然是多个,要获取值的元素一定是表达式的最后一个元素,在最后一个元素后面添加“$”。比如,表达式“root/a/b/d$”就表示获取根元素下,a元素下,b元素下的多个d元素的值的集合。
4.获取相同元素名称的属性的值,当然也是多个:要获取属性值的元素一定是表达式的最后一个元素,在最后一个元素后面添加"$"。比如,表达式“root/a/b/d$.id$”就表示获取根元素下,a元素下,b元素下的多个d元素的id属性的值的集合。

上面的xml,对应的抽象语法树,可能的结构如图:

javascript模式,javascript模式 pdf,javascript,高性能javascript,javascript的设计模式,javascript 单例模式,javascript观察者模式,javascript工厂模式,javascript 严格模式
下面我们来看看具体的代码:
1.定义上下文:

复制代码 代码如下:


/**
 * 上下文,用来包含解释器需要的一些全局信息
 * @param {String} filePathName [需要读取的xml的路径和名字]
 */
function Context(filePathName) {
    // 上一个被处理元素
    this.preEle = null;
    // xml的Document对象
    this.document = XmlUtil.getRoot(filePathName);
}

Context.prototype = {
    // 重新初始化上下文
    reInit: function () {
        this.preEle = null;
    },
    /**
     *  各个Expression公共使用的方法
     * 根据父元素和当前元素的名称来获取当前元素
     * @param  {Element} pEle    [父元素]
     * @param  {String} eleName [当前元素名称]
     * @return {Element|null}         [找到的当前元素]
     */
    getNowEle: function (pEle, eleName) {
        var tempNodeList = pEle.childNodes;
        var nowEle;

        for (var i = 0, len = tempNodeList.length; i < len; i++) {
            if ((nowEle = tempNodeList[i]).nodeType === 1)
                if (nowEle.nodeName === eleName)
                    return nowEle;
        }

        return null;
    },
    getPreEle: function () {
        return this.preEle;
    },
    setPreEle: function (preEle) {
        this.preEle = preEle;
    },
    getDocument: function () {
        return this.document;
    }
};

在上下文中使用了一个工具对象XmlUtil来获取xmlDom,下面我使用的是DOM3的DOMPaser,某些浏览器可能不支持,请使用搞基浏览器:

复制代码 代码如下:


 // 工具对象
    // 解析xml,获取相应的Document对象
    var XmlUtil = {
        getRoot: function (filePathName) {
            var parser = new DOMParser();
            var xmldom = parser.parseFromString('12345d1d2d3d4', 'text/xml');

            return xmldom;
        }
    };

下面就是解释器的代码:

相关图片

相关文章