IT技术博客大学习 共学习 共进步

关于Javascript的俩个有趣的探讨

风雪之隅 2009-10-30 08:52:41 浏览 3,302 次

关于事件处理函数引用的一个佐证

之前, 我在分析Javascript的This关键字的时候, 说过, 当使用inline的方式写dom元素的事件处理函数的时候, 采用的是引用的方式. 刚好nullbyte童鞋给我提供了一个很有意思的Case:

以下是代码片段:
<img id="foo" src="xxx" onerror=" alert(’error’);
    } function foobar() {
          alert(’www.laruence.com’); " />
<script>
alert(document.getElementById("foo").onerror);
</script>

在IE下试试看..

不过, FF和Chrome下都不行, 应该是FF和Chrome都会验证html代码的合法性.

Javascript正则的效率

如果你看到有人写Javascript的trim的时候采用了循环的方式,而不是正则的方式, 请不要笑. 人家这可是经验所致, 考虑如下代码的执行时间会是多少?

以下是代码片段:
var matchs = /^(a+)+$/.exec("aaaaaaaaaaaaaaaaaaaaaaaaaaaX");
alert(matchs);

告诉你吧…. 注:以下结果来自看手表估测, 但不影响时间的长度性…另外jsmore的stauren同学也验证了这一结论:

以下是引用片段:
IE8: 30秒
FF3: 28秒
号称目前最快的采用V8引擎的Chrome: 8秒.

这个结果,,,是多么的不可接受啊? 具体原因的分析, 在master regular expression里面有提到过.

以下是引用片段:
NFA和DFA的引擎是有区别的。js/perl/php/java/.net都是NFA引擎。
而DFA与NFA机制上的不同带来5个影响:
1. DFA对于文本串里的每一个字符只需扫描一次,比较快,但特性较少;NFA要翻来覆去吃字符、吐字符,速度慢,但是特性丰富,所以反而应用广泛,当今主要的正则表达式引擎,如Perl、Ruby、Python的re模块、Java和.NET的regex库,都是NFA的。
2. 只有NFA才支持lazy和backreference(后向引用)等特性;
3. NFA急于邀功请赏,所以最左子正则式优先匹配成功,因此偶尔会错过最佳匹配结果;DFA则是“最长的左子正则式优先匹配成功”。
4. NFA缺省采用greedy量词(就是对于/.*/、/\w+/这样的“重复n”次的模式,以贪婪方式进行,尽可能匹配更多字符,直到不得以罢手为止),NFA会优先匹配量词。
5. NFA可能会陷入递归调用的陷阱而表现得性能极差。
backtracking(回朔)
当NFA发现自己吃多了,一个一个往回吐,边吐边找匹配,这个过程叫做backtracking。由于存在这个过程,在NFA匹配过程中,特别是在编写不合理的正则式匹配过程中,文本被反复扫描,效率损失是不小的。明白这个道理,对于写出高效的正则表达式很有帮助。 

而对于Javascript中的正则来说, 应该是优先匹配量词, 导致了很深的递归, 形成了性能问题…

建议继续学习

  1. grep 正则表达式选项要记得转义 (阅读 6,442)
  2. 统计最近用过的linux命令 (阅读 6,402)
  3. 正则表达式基础 (阅读 6,160)
  4. 正则表达式的与或非 (阅读 5,741)
  5. 学习Grep,Sed中的正则 (阅读 5,263)
  6. Js事件监听封装(支持匿名函数) (阅读 4,920)
  7. URL正则表达式 (阅读 4,660)
  8. 正则表达式简要入门 (阅读 4,362)
  9. 正则转义符汇总 (阅读 4,320)
  10. 使用Oracle正则表达式监控应用到数据库的连接情况 (阅读 4,262)