ActionScript 3中的E4X实现的小实验

ActionScript 3或许是现在最接近 ECMAScript Edition 4的实现了.其中也包含了对 ECMAScript for XML (E4X)的实现(之前最早实现对E4X支持的应该是BEA Weblogic Workshop吧).

Professional JavaScript for Web Developers里, 20.2 ECMAScript for XML里对E4X的描述有点过时了.至少20.2.1里开头的好几个例子都不符合于现在的规范了(E4X 2nd).而当前AS3对E4X的实现应该是对的吧...我还没时间仔细把E4X的规范通读.

下面稍微展现几个有趣的地方,例如说新加入的获取/修改XML节点内容的方法, ".."运算符, for each循环等.要写得更详细那就变教程了,我只想在这里展示些有趣的东西而已.
var node : XML = <books>
    <book type="paperback">
        Author1, Book 1
        <!--
        <author>Author1</author>
        <name>Book 1</name>
        -->
    </book>
    <book type="hardcover">
        <author>Author2</author>
        <name>Book 2</name>
    </book>
</books>;

var typeOfBook1 : String = node.book[0].@type; // fetch the type of the first <book>
// node.["book"][0].@["type"] will work too.
// this gets around keyword conflict problems
print( typeOfBook1 );
// Output:
// paperback

print( );

var nameOfBook2 : String = node.book[1].name; // fetch the <name> of the second <book>
print( nameOfBook2 );
// Output:
// Book 2

print( );

var list : XMLList = node..book; // fetch the list of <book> nodes from the given node
for ( var index in list ) {
    print( index );
}
// Output:
// 0
// 1

print( );

for each ( var val in list ) {
    print( val );
}
// Output:
// Author1, Book 1
// <book type="hardcover">
//   <author>Author2</author>
//   <name>Book 2</name>
// </book>

list = <>
    <a>Something</a>
    <a>Something else</a>
</>; // XMLList literal

list[0] = "Something first"; // same as <a>Something first</a> here

for each ( var value in list ) {
    print( value );
}
// Output:
// Something first
// Something else

var node : XML = <books return="mi">
    <book type="paperback">
        Author1, Book 1
    </book>
</books>;

print( node.@["return"] ); // get around AS3 keywords with alternative syntax

这些新玩具比XPath看起来亲切多了 ...T T
不过要用XLST的话还是得靠XPath ...T T

var process : XML = <process>
</process>

var state1 : XML = <state></state>
state1.@g = '123,456'
state1.@name = 'my name1'

process.appendChild( state1 )

var state2 : XML = <state></state>
state2.@g = '12344'
state2.@name = 'my name2'

process.appendChild( state2 )

print(process)
// Output:
// <process>
//   <state g="123,456" name="my name1"/>
//   <state g="12344" name="my name2"/>
// </process>

var books : XML = <books xmlns="abcdefgh">
  <book>
    <name>Book Title 1</name>
  </book>
  <book>
    <name>Book Title 2</name>
  </book>
</books>

var bookNS : Namespace = new Namespace('abcdefgh')
print(books.bookNS::book)
print()
print(books.bookNS::book.bookNS::name[0])
// Outputs:
// <book xmlns="abcdefgh">
//   <name>Book Title 1</name>
// </book>
// <book xmlns="abcdefgh">
//   <name>Book Title 2</name>
// </book>
//
// Book Title 1


传闻Java SE 7也有在语言级别支持XML的可能,不知道如果真的实现的话,是否也会跟E4X很像呢?

话说回来,ES4里新增加的内容多得真够戗.于是又有很多人在抱怨"kitchen-sink"问题了;不,更多的是说"over engineered".原本的JS1/ES1/ES2/ES3确实是比不少语言简单,但真要说"很简单"也未必.光是有first-class function就已经有不少复杂度了;对不习惯prototype based OO的人来说,只有原型而没有"类"或许也是难以理解的地方.
新的ES4的话...嗯嗯,不好说.《人月神话》里有个经典的说法: "the second system syndrome",这在ES4上真是...
ES4的overview里有这么一句话:
引用
The reason for introducing type annotations into ECMAScript is their benefit to programming in the large, not their potential benefits to performance.

虽说"不只是为了性能",但性能不得不说是其中的重要考虑因素.之前我还跟师兄开玩笑,说要是照这种势头,既然变量是"为了提高运行效率"而可以指定类型,那容器类最好也能指定其内容的类型,然后我们就有...泛型容器了.事实上,ES4里我们可以写:
Vector.<int>

眼熟么? ...用过C++/Java SE 5 or later/C# 2.0 or later的人肯定会觉得眼熟.
C++:
vector<int>

Java:
ArrayList<Integer>

C#:
List<int>

也难怪有人说ES4几乎包含了这几十年来OO发展中出现的所有东西...

我对ES4还是抱有不少憧憬了,希望它能活下去吧.ES4只是来得太迟了而已,说不定要是再早一点就能赶上Ajax的趟了?

回头留意下InfoQ上的一篇报导: Is the future of JavaScript ECMAScript 4?

你可能感兴趣的:(JavaScript,xml,weblogic,OO,actionscript)