[转]让你的Flex MXML和ActionScript 3代码更规范:第二篇:措辞用法篇

Language Usage(措辞用法)
这个部分讨论如何构建好我们的ActionScript 3代码,特别遇到我们有多种方式表达同一个意思的时候。

--------------------------------------------------------------------------------------------------------

编译选项(Compilation options)
编译使用选项-strict(严格类型)和-show-actionscript-warnings(如字面意思就是会报警告),这些都作为默认设置写在flex-config.xml文件中

--------------------------------------------------------------------------------------------------------

基于属性的公共接口(Property-based APIs)
在公共接口实现中选择基于属性,而不是基于方法,这样做可以在MXML语法中更便捷的使用设置属性。

--------------------------------------------------------------------------------------------------------

类型声明(Type declarations)
为每一个常量、变量、函数参数和函数返回值声明所属类型,就算是简单的标注 "*" 类型也不要不标注任何类型

推荐如下:

var value:*;

不推荐:

var value;恰当的选中最符合的类型。比如,一个循环序号应该是int类型,而不是Number,当然更不会是Object和*。再举个例子,一个mouseDownHandler应该申明其参数event的类型为MouseEvent,而不是Event

给整数使用int类型,尽管他们不可能是负数,给RGB颜色值、声音比特和其他非数字的值使用uint类型

只在值不能确定类型的时候使用*,一般情况下你应该使用Object而不是*,因为null表示"Object不存在"

如果你申明一些东西为Array类型,当明确数组要素的类型后,请立即加上/* 数组要素类型 */这样的注释,一个即将来临的版本很有可能使用表明类型的Array

推荐如下:

var a:Array /* of String */ = [];不推荐:var a:Array = [];推荐做法:

function f(a:Array /* of Number */):Array /* of Object */
{
    ...
}不推荐:function f(a:Array):Array--------------------------------------------------------------------------------------------------------

iterals
undefined
尽可能避免使用这个,只有在处理编译时候的*类型值和尽量节省使用*的时候才使用



int 和 uint 使用
在整数中不使用小数点

推荐做法:

2不推荐:

2.在十六进制中使用小子字母x和大写字母A-Z推荐做法:

0xFEDCBA不推荐:0Xfedcba在写一个RGB颜色值时总是使用6个字母来表示十六进制数值推荐做法:

private const BLACK:uint = 0x000000;不推荐:

private const BLACK:uint = 0;  当处理索引的时候,使用-1来表示没有索引 Number使用(Number literals)
如果一个Number类型数值可能是分数,则注明小数点,在小数点后紧跟一个0

推荐做法:

alphaFrom = 0.0;
alphaTo = 1.0;不推荐:alphaFrom = 0;
alphaTo = 1;然而不用按上面的规则对待坐标,尽管它们原则是分数,但习惯上约定是整数推荐:

var xOffset:Number = 3;不推荐:var xOffset:Number = 3.0;当使用指数标法的时候应该使用e而不是E推荐:

1.0e12不推荐:

1.0E12对于一个没有设值的数值,则设置为默认值NaN String使用(String literals)
使用双引号而不是单引号去划分字符串,尽管那个字符串中包换有双引号

推荐:

"What's up, \"Big Boy\"?"不推荐:'What\'s up, "Big Boy"?'对于unicode编码使用\u而不是\U Array写法(Array literals)
使用Array标示比new Array()更佳

推荐:

[]不推荐:

new Array()推荐:

[ 1, 2, 3 ]不推荐:

new Array(1, 2, 3)只有当需要定义数组大小时候才使用Array构造,不如new Array(3),表示[ undefined, undefined, undefined ],而不是[3]



Object写法(Object literals)
使用Object标示比new Object()更佳

推荐:

{}不推荐:

new Object()推荐:

o = { a: 1, b: 2, c: 3 };不推荐:

o = new Object();
o.a = 1;         
o.b = 2;         
o.c = 3;或者 = {};
o.a = 1;         
o.b = 2;         
o.c = 3; Function写法(Function literals)
避免使用function来定义没从属的函数,使用类方法或者包函数来替代

如果你必须使用function来定义,注明返回值,在函数体中最后部分使用分号来终结

推荐:

function(i:int):void { doIt(i - 1); doIt(i + 1); }不推荐:

function(i:int) { doIt(i - 1); doIt(i + 1) } 正则表达式(RegExp literals)
使用标示而不是正则表达式RegExp构造

推荐:

var pattern:RegExp = /\d+/g;不推荐:

var pattern:RegExp = new RegExp("\\d+", "g"); XML and XMLList literals
使用符号标示而不是直接XML构造函数

推荐:

var node:XML = <name first="Jane" last="Doe"/>;不推荐:

var node:XML = new XML("<name first=\"Jane\" last=\"Doe\"/>");在XML属性值中使用双引号而不是单引号

推荐:

var node:XML = <name first="Jane" last="Doe"/>;不推荐:

var node:XML = <name first='Jane' last='Doe'/>; 类写法(Class literals)
只有在导入的两个同名类时候,为了消除歧义才使用类的完成名字

推荐:

import mx.controls.Button;
...
var b:Button = new Button();不推荐:import mx.controls.Button;
...
var b:Button = new mx.controls.Button();


但对于同名类就必须要完整路径

import mx.controls.Button;
import my.controls.Button;
...
var b:Button = new mx.controls.Button();

--------------------------------------------------------------------------------------------------------

表达式(Expressions)
括号
在+, -, *, /, &&, ||, <, <=, >, >=, ==, 和 !=之类平常操作符间,避免使用不必要的括号

推荐:

var e:Number = a * b / (c + d);不推荐:

var e:Number = (a * b) / (c + d);推荐:

var e:Boolean = a && b || c == d;不推荐:

var e:Boolean = ((a && b) || (c == d));对于其他操作符,因为优先级太难记忆,所以括号有助于理解优先



强制类型转化(Coercion)
对于一个已经是Boolean类型的值不要跟true或者false比较

推荐:

if (flag)不推荐:

if (flag == true)推荐:

var flag:Boolean = a && b;不推荐:

var flag:Boolean = (a && b) != false;明确int,unit,Number或者String的Boolean值条件:

推荐:

if (n != 0)不推荐:

if (n)推荐:

if (s != null && s != "")不推荐:

if (s)让object引用含蓄表达Boolean值:

推荐:

if (child)不推荐:

if (child != null)推荐:

if (!child)不推荐:

if (child == null)当强制类型转换可能失败或者你想你的表达式计算出null而不是抛出异常,应该使用as操作符

推荐:

IUIComponent(child).document不推荐:

(child as IUIComponent).document 比较(Comparison)
写比较表达式应该让他们读起来更自然:

推荐:

if (n == 3) // "if n is 3"不推荐:

if (3 == n) // "if 3 is n" ++和--操作符(++ and -- operators)
当前置和后置等价的情况下,使用后置方式。只有在你需要在之前运行自增运算时候才使用前置

推荐:

for (var i:int = 0; i < n; i++)不推荐:

for (var i:int = 0; i < n; ++i) 三元操作符(Ternary operator)
使用三元操作符来代替简单的if/else部分,特别是null的检测:

推荐:

return item ? item.label : null;不推荐:

if (!item)
    return null;
return item.label;但不用嵌套三元操作符来代替负载的if/else逻辑

推荐:

if (a < b)
    return -1;
else if (a > b)
    return 1;
return 0;不推荐:

return a < b ? -1 : (a > b ? 1 : 0); new操作符(new operator)
在类后加上花括号,尽管类的构造函数没有参数.

推荐:

var b:Button = new Button();不推荐:

var b:Button = new Button;--------------------------------------------------------------------------------------------------------

指令(Statements)
在每个指令后面加上分号,不要使用ActionScript 3的可选分号功能

推荐:

a = 1;
b = 2;
c = 3;不推荐:

a = 1
b = 2
c = 3 include指令(include statements)
使用include,而不是#include,如其他指令结束后,include指令结束后也用分号

推荐:

include "../core/ComponentVersion.as";不推荐:

#include "../core/ComponentVersion.as"使用相对地址而不是绝对地址



import指令(import statements)
导入指定的类、接口和包级别这种做法优于使用*来全部导入.

推荐:

import mx.controls.Button;
import flash.utils.getTimer;不推荐:

import mx.core.*; use namespace指令(use namespace statements)
尽量避免使用命名空间;在没有打开命名空间的时候使用::符号来调用命名空间

推荐:

import mx.core.mx_internal;

// Later, in some method...
mx_internal::doSomething();不推荐:

import mx.core.mx_internal;
use namespace mx_internal;

// Later, in some method...
doSomething(); if指令(if statements)
如果if/else分支区块只有一个指令,不要把它包括进去{}中

推荐:

if (flag)
    doThing1();不推荐:

if (flag)
{
    doThing1();
}推荐:

if (flag)
    doThing1();
else
    doThing2():不推荐:

if (flag)
{
    doThing1();
}
else
{
    doThing2();
}但如果任何一个分支有多个指令,把所有分支指令都囊括进相应的{}

推荐:'

if (flag)
{
    doThing1();
}
else
{
    doThing2();
    doThing3();
}不推荐:

if (flag)
    doThing1();
else
{
    doThing2();
    doThing3();
}当做多个错误检测时候,及早是哟偶那个连续的if指令来测试错误和相应的返回信息,成功的执行将在方法最后成功返回,不要让测试之间相互影响,那会让测试执行流动难以控制

推荐:

if (!condition1)
    return false;
...
if (!condition2)
    return false;
...
if (!condition2)
    return false;
...
return true;不推荐:

if (condition1)
{
    ...
    if (condition2)
    {
        ...
        if (condition3)
        {
            ...
            return true;
        }
    }
}
return false; for指令(for statements)
把循环体都放在{}中,尽管可能只有一个指令

推荐:

for (var i:int = 0; i < 3; i++)
{
   doSomething(i);
}不推荐:

for (var i:int = 0; i < 3; i++)
    doSomething(i);使用局部变量存储for循环的索引上线,这样可以在每次循环中不用重新计算

推荐:

var n:int = a.length;
for (var i:int = 0; i < n; i++)
{
    ...
}不推荐:

for (var i:int = 0; i < a.length; i++)
{
    ...
}在for指令{}中定义循环变量,除非在其他地方会重用推荐:

for (var i:int = 0; i < 3; i++)不推荐:

var i:int;
for (i = 0; i < 3; i++)
{
   ...
} while指令(while statements)
把循环体都放在{}中,尽管可能只有一个指令

推荐:

while (i < n)
{
   doSomething(i);
}不推荐:

while (i < n)
    doSomething(i); do指令(do statements)
把循环体都放在{}中,尽管可能只有一个指令

推荐:

do
{
   doSomething(i);
}
while (i < n);不推荐:

do
    doSomething(i);
while (i < n); switch指令(switch statements)
取保switch区域中每个case以及default处理分支都在相应的{}中,每个分支放相应的break或者reture,而不是在分支后面,如果选择return不要在return后加入break,对待default分支也一样

推荐:

switch (n)
{
    case 0:
    {
        foo();
        break;
    }

    case 1:
    {
        bar();
        return;
    }

    case 2:
    {
        baz();
        return;
    }

    default:
    {
        blech();
        break;
    }
}不推荐:

switch (n)
{
    case 0:
        foo();
        break;

    case 1:
    {
        bar();
    }
    break;

    case 2:
        baz();
        return;
        break;

    default:
        blech();
} return指令(return statements)
不要在return中放入不必要的括号

推荐:

return n + 1;不推荐:

return (n + 1);在一个方法的中间返回也是可以的

--------------------------------------------------------------------------------------------------------

声明(Declarations)
不要在一个声明中声明多个变量或常量

推荐:

var a:int = 1;
var b:int = 2;不推荐:

var a:int = 1, b:int = 2; override关键字(The override keyword)
就现在而已,把override放在最前,而不是存取说明符(public protected private)后面

推荐:

override protected method measure():void不推荐:

protected override method measure():void 存取说明符(Access specifiers)
在允许的前提下,尽可能添加上详尽的存取说明符,不要依靠internal这种如果不写就默认的存取说明符

在确定一个API是public还是protected前,想清楚它是否真的如此。Public和Protected的API都应该有相应的文档,在被正式反对前,这些都将一直被维护持续几个版本



static关键字(The static keyword)
现在而言,把它放在存储说明符后面

推荐:

public static const MOVE:String = &quot;move&quot;不推荐:

static public const MOVE:String = &quot;move&quot;; final关键字(The final keyword)
现在而言,把它放在存储说明符后面

推荐:

public final class BoxDirection不推荐:

final public class BoxDirection声明说有枚举类为final

也声明基属性已经那些有$的方法为final



常量(Constants)
所有的常量类型都应该是static,这样所有实例都将存储同一个值

推荐:

public static const ALL:String = "all";不推荐:

public const ALL:String = "all"; 变量(Variables)
如果一个变量需要初始化至不是默认值的值,把这步操作放在声明中欧偶那个而不是构成过程

推荐:

private var counter:int = 1;不推荐:

private var counter:int;
...
public function MyClass()
{
    super();
    ...
    counter = 1;
} 局部变量(Local variables)
在需要第一次时候局部变量前,而不是在函数的开头

推荐:

private function f(i:int, j:int):int
{
    var a:int = g(i - 1) + g(i + 1);
    var b:int = g(a - 1) + g(a + 1);
    var c:int  = g(b - 1) + g(b + 1);

    return (a * b * c) / (a + b + c);
}不推荐:private function f(i:int, j:int):int
{
    var a:int;
    var b:int;
    var c:int;

    a = g(i - 1) + g(i + 1);
    b = g(a - 1) + g(a + 1);
    c = g(b - 1) + g(b + 1);

    return (a * b * c) / (a + b + c);
}在每个函数中申明局部变量

推荐:

var a:int;
if (flag)
{
    a = 1;
    ...
}
else
{
    a = 2;
    ...
}不推荐:

if (flag)
{
    var a:int = 1;
    ...
}
else
{
    var a:int = 2;
    ...
}推荐:

var i:int;
for (i = 0; i &lt; n; i++)
{
    ...
}

for (i = 0; i &lt; n; i++)
{
    ...
}不推荐:

for (var i:int = 0; i &lt; n; i++)
{
    ...
}

for (var i:int = 0; i &lt; n; i++)
{
    ...
} 类(Classes)
如果一个类由Object派生,这些代码可以省略

The only "bare statements" in a class should be calls to static class initialization methods, such as loadResources().



构造函数(Constructors)
如果一个类有实例,写一个构造函数,确保明确执行super(),尽管这步什么没有执行

如果构造函数需要设置实例变量,把他们的名字设置成一样的

推荐:

public function MyClass(foo:int, bar:int)
{
    this.foo = foo;
    this.bar = bar;
}不推荐:

public function MyClass(fooVal:int, barVal:int)
{
    foo = fooVal;
    bar = barVal;
}不要在构造函数中设置类变量的值,这步应该在变量的申明中完成,然而如果你需要重新设置,那就在构造函数中执行



接口(Interfaces)
待续(真的TBD)



命名空间(Namespaces)
待续



Implementing properties
TBD


Metadata
TBD


包(Packages)
One public API (usually a class, sometimes a namespace or function) inside the package statement.

Helper classes

bare statements

Good Luck & Have Fun!
posted @ 2011-10-26 22:29  Stranger  阅读(111)  评论(0编辑  收藏  举报