10月26, 2009

javascript中关于try,finally控制语句的使用

几乎每个脚本语言都有try,catch,finally控制语句。try,catch控制语句主要是对有异常的程序控制,这里不在详细描述。主要讲述下try,finally的妙用。

在正文之前,给出2个已有的两个应用(2篇文章都是在51JS中),如下:

1、try finally 妙用,防止内存泄漏

2、月影发的“某人发给我的邪恶代码”,可以看#16楼 lifesinger的回复。

问题的表面

也许你对上面2个应用还没有真正的明白,也可能你看到这样的代码心里忍不住和我一样惊叹一声“绝”。那么为什么能够写出这样的代码,这样的代码又是怎样工作的呢?一切从ECMA-262开始说起。

揭开面纱

如果你还不知道什么是ECMA-262或者还没有阅读过这个标准,那么我建议你还是尽快花点时间好好看看,有兴趣更要研究。你可以从它的官方网站下载,如果不想看PDF版本的话可以打印出来的。我以前看的时候就是打印出来慢慢研究的。

在ECMA262的12.14 (P70)The try statement有:

The production TryStatement : try Block Finally is evaluated as follows:

1. Evaluate Block.

2. Evaluate Finally.

3. If Result(2) .type is normal, return Result(1).

4. Return Result(2). 上述中第一步和第二部分别是计算Block和Finally的值。第三步是进行第二步结果类型的判断,如果类型是normal的话,返回第一步的结果否则返回第二步的结果。

这里有两点比较特殊,一个是返回结果在进行计算Finally块后才进行的,二是第二步的结果类型是normal的时候,返回第一步的结果,否则返回第一步的结果。

对于第一点,前面的防止内存泄露就是一个很好的应用。充分使用了这一特性。

那第二步的结果类型什么时候是normal呢。这里的类型是实现JS引擎层面上的类型,用JS是获取不到的。

JS引擎层面的类型在ECMA262中的8.9进行了定义:

8.9 The Completion Type

The internal Completion type is not a language data type. It is defined by this specification purely for

expository purposes. An implementation of ECMAScript must behave as if it produced and operated upon

Completion values in the manner described here. However, a value of the Completion type is used only as

an intermediate result of statement evaluation and cannot be stored as the value of a variable or property.

The Completion type is used to explain the behaviour of statements (break, continue, return and throw) that perform nonlocal transfers of control. Values of the Completion type are triples of the form

(type, value, target), where type is one of normal, break, continue, return, or throw, value is any

ECMAScript value or empty, and target is any ECMAScript identifier or empty.

The term “abrupt completion” refers to any completion with a type other than normal. 也就是说,在JS引擎中,有break, continue, return, throw和normal五种完成类型。那么我们就可以知道当finally语句块含有break, continue, return, throw语句被执行时,返回值是第二步的结果,否则为第一步的结果。

上面提到的第二个应用就是基于这一特性的,虽然应用中提到的知识简单的返回结果。但在实际项目中,可以根据这一特性得到不同的返回值。

本文链接:http://welefen.com/post/javascript-try-finally.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。