Skip to content

Latest commit

 

History

History
55 lines (40 loc) · 2.97 KB

File metadata and controls

55 lines (40 loc) · 2.97 KB

7.3 Compiling regular expressions

正则表达式在使用中分好几个阶段,理解这些阶段对于代码优化大有裨益。其中最主要的2个阶段是"编译"和"执行"。 编译发生在表达式第一次创建的时候,执行则发生在匹配的时候。

编译时js引擎会把表达式解析成内部表达形式,通常浏览器会有自己的优化机制,会把之前编译好的缓存起来,如果2个表达式一样就用之前那个。 当然,作为一名忍者,我们不能认为所有浏览器都有这种优化。对于复杂的正则表达式,通过预编译我们能观察到明显的性能提升。

在7.2中我们知道有2种预编译方法,并介绍了2者的区别。下面我们来看一个具体例子,进一步说明构造器方法的优越性。 这个例子的功能是判断一个dom是否还有指定的classname。classname是动态指定的。

Listing 7.3 Compiling a runtime regular expression for later use

    <div class="samurai ninja"></div>                          <!--#1-->
    <div class="ninja samurai"></div>                          <!--#1-->
    <div></div>                                                <!--#1-->
    <span class="samurai ninja ronin"></span>                  <!--#1-->

    <script>
      function findClassInElements(className, type) {

        var elems =                                            //#2
          document.getElementsByTagName(type || "*");

        var regex =                                            //#3
          new RegExp("(^|\\s)" + className + "(\\s|$)");

        var results = [];                                      //#4

        for (var i = 0, length = elems.length; i < length; i++)
          if (regex.test(elems[i].className)) {                //#5
            results.push(elems[i]);
          }
        return results;
      }

      assert(findClassInElements("ninja", "div").length == 2,
             "The right amount fo div ninjas was found.");
      assert(findClassInElements("ninja", "span").length == 1,
             "The right amount of span ninjas was found.");
      assert(findClassInElements("ninja").length == 3,
             "The right amount of ninjas was found.");
    </script>

这段代码首先声明了几个元素供测试,然后定义了一个函数,用来寻找dom中是否含有指定的className 因为className是动态指定的,所以只能使用new RegExp构造。

listing7.3中正则的含义是:匹配开头,或者空格后紧跟着className,然后跟着空格或者结尾的模式。注意在字符串中我们必须用 \\表示一个反斜杠。最好把“或”的前后部分括起来,这是个好习惯。之前讲过,括号具有双重含义,下面我们就来讲讲“捕获”

findClassInElements函数没有对未定义的className进行判断,如果不指定,className就变成"undefined"字符串,会匹配class=undefined 的类。所以在用字符串构造正则的时候,这一点需要谨慎。