ActionScript3.0 基本语法 - Notes

来源:互联网 发布:蓝月传奇翅膀进阶数据 编辑:程序博客网 时间:2024/05/16 02:16

ActionScript和JavaScript都基于共同标准ECMAScript, 所以两者很多语法, 概念都是相似的或者是完全相同的.

class and object

AS3.0中的object与C++/java中不同: “Every variable you declare, every function you write, and every class instance you create is an object. You can think of an ActionScript 3.0 program as a group of objects that carry out tasks, respond to events, and communicate with one another.” 理解了这个很多现象都可以理解了. 这样以下的定义都是正确的:

// file HelloWorld.as
package
{
public class HelloWorld
{
}
}
// file HelloWorld.as
package
{
public function HelloWorld():void
{
}
}
// file HelloWorld.as
package
{
var HelloWorld:String;
}

而实际上 “ One subtle difference between classes in ActionScript and classes in Java or C++ is that in ActionScript, classes are not just abstract entities. ActionScript classes are represented by class objects that store the class’s properties and methods. ” 这就是说在AS3.0的class中甚至可以包含可执行的语句, 而不仅仅是声明和定义, 如下代码是正确的, 而在C++/java则是不可能的:

 package tony.helloWorld
{
class HelloWorld
{
var abc:String = “”;
abc = “Hello World!”;// it is correct here, but not in C++/java
}
}

package and namespace

AS3.0中的package与java中的package在概念, 作用和使用上都很相似, 不同的是AS3.0中只能定义一个object, 且object的名字与文件名相同, 这里的object包括class, variable, function, namespace, 且他们的namespace必须为public/internal. 下面一段代码会引起编译错误: “A file found in a source-path can not have more than one externally visible definition.”. 因为匿名package中包含两个objects: class HelloWorld and variable v.

// file HelloWorld.as
package
{
public class HelloWorld
{
}
var v:String;// compile error
}

如果这些定义放在包外是没问题的, 但不能是public, 如下是正确的代码:

// file HelloWorld.as
package
{
public class HelloWorld
{
}
}
function f():void;
var v:String;

AS3.0中的namespace与C++是完全不同概念, 它实际上相当于修饰符个概念, 感觉, 它是专门用来控制访问权限的, 而C++中的namespace主要用处是为了避免命名冲突的.

AS3.0中的namespace包括public, internal, private, protected, costom-defined namespace. 默认是internal, 前四个作用域和java还是很类似的, 不过这里private and protected只能用来修饰class中的属性 (变量) 和方法 (函数), 而costom-defined namespace不能用来修饰class, public只能在package内使用. 我们经常碰到一个错误: “1114: The public attribute can only be used inside a package.” 就是这个问题

这里需要注意的是, AS3.0对于包外使用public的定义似乎并不严格, 只有在使用某个AS脚本文件时, 才会去检查, 并生成compile error. 如下代码:

// file HelloWorld.as
package tony.helloWorld
{
public class HelloWorld
{
}
}
public function f():void;
public var v:String;

如果不使用这个文件, 或者仅仅是import tony.helloWorld.HelloWorld; 编译时都不会出错, 但我若使用了class HelloWorld, 在编译期间就是出现代码为1114的这个error.

另外, 如果仅仅是一个AS脚本文件, 其中没有定义任何包啊类啊, 比如:

// HelloWorld.as
public function hehe():String
{
return "hehe";
}

public var v:String;

无论定义多少个public的东西, 无论都没使用里面的变量函数, 都不会编译出错. 而这里通常是通过包含这个脚本去引用里面的变量函数, 这时public丝毫不起作用, 加不加一样, 所以没有编译错误也是可以理解的, 只是”The public attribute can only be used inside a package.” 这种说法是够歧义的.

Variable and its Scope

AS3.0与前几个版本不同, 定义变量必须使用var, 但可以不指定类型, 如下:

var numArray:Array = ["zero", "one", "two"];
var myObject:Object = {propA:1, propB:2, propC:3};
var i;
var a:int = 10, b:int = 20, c:int = 30;

“In ActionScript 3.0, variables are always scoped to the function or class in which they are declared. A global variable is a variable that you define outside of any function or class definition. ActionScript variables, unlike variables in C++ and Java, do not have block-level scope, just as JavaScript. ”

The compiler moves all variable declarations to the top of the function, which is called hoisting. But the complier will not hoist any assignment statements. It is just like JavaScript, too.

trace(num); // output: NaN 
var num:Number = 10;
trace(num); // output: 10

Variable default values:

Data type Default value Boolean false int 0 Number NaN Object null String null uint 0 Not declared (equivalent to type annotation *) undefined All other classes, including user-defined classes. null

“The value null is not a valid value for variables of type Boolean, Number, int, or uint. If you attempt to assign a value of null to a such a variable, the value is converted to the default value for that data type. For variables of type Object, you can assign a value of null. If you attempt to assign the value undefined to a variable of type Object, the value is converted to null. ”

“A primitive value is a value that belongs to one of the following data types: Boolean, int, Number, String, and uint. ActionScript stores primitive values internally as immutable objects. The fact that they are stored as immutable objects means that passing by reference is effectively the same as passing by value. All values, even primitive values, are objects. ”

AS3.0中用is来检测类型, 返回的是true/false, 用instanceof会有问题, 因为in ActionScript 3.0, the prototype chain does not provide a complete picture of the inheritance hierarchy.

var mySprite:Sprite = new Sprite(); trace (mySprite is Sprite); // output: true

AS3.0中也可以用as来检测类型, 只是返回的值是被检测表达式的值或null.

“A dynamic class defines an object that can be altered at run time by adding or changing properties and methods. A class that is not dynamic, such as the String class, is a sealed class. You create dynamic classes by using the dynamic attribute when you declare a class. Properties that you add to an instance of a dynamic class are run-time entities, so any type checking is done at run time. You cannot add a type annotation to a property that you add in this manner. Methods created in this way, however, do not have access to any private properties or methods of the Protean class. Moreover, even references to public properties or methods of the Protean class must be qualified with either the this keyword or the class name.”

因为AS3.0中class 本身就是一个对象, 所以动态的加属性和变量很正常, 这在JavaScript中很常见, 只是AS3.0对变量定义更严格 (var), 所以看上去dynamic class好像很特别.

dynamic class Protean 
{
}
var myProtean:Protean = new Protean();
myProtean.aString = "testing";
myProtean.aNumber = 3;
myProtean.traceProtean = function ()
{
trace (this.aString, this.aNumber);
}

Syntax

“The for..in loop iterates through the properties of an object, or the elements of an array. The for each..in loop iterates through the items of a collection, which can be tags in an XML or XMLList object, the values held by object properties, or the elements of an array.”

var myXML:XML = <users>
<fname>Jane</fname>
<fname>Susan</fname>
<fname>John</fname>
</users>;
for each (var item in myXML.fname)
{
trace(item);
}
/* output
Jane
Susan
John
*/

大部分语法, 与JavaScript相同, 就不说了, 关于Function, 摘了几点:

“A function is called a method if you define it as part of a class definition or attach it to an instance of an object. A function is called a function closure if it is defined in any other way.”

“The first difference is that function expressions do not exist independently as objects with regard to memory management and garbage collection. The second difference between function statements and function expressions is that function statements exist throughout the scope in which they are defined, including in statements that appear before the function statement.”

“A nested function is available only within its parent function unless a reference to the function is passed to external code.”

“In ActionScript 3.0, all arguments are passed by reference because all values are stored as objects. However, objects that belong to the primitive data types, which includes Boolean, Number, int, uint, and String, have special operators that make them behave as if they were passed by value.”

Default parameter values与C++很像, 如下:

function defaultValues(x:int, y:int = 3, z:int = 5) 
{
trace (x, y, z);
}
defaultValues(1); // output: 1 3 5

The arguments object

The arguments object is an array that includes all the parameters passed to the function.
The arguments.length property reports the number of parameters passed to the function.
The arguments.callee property provides a reference to the function itself, which is useful for recursive calls to function expressions.

The arguments object is not available if any parameter is named arguments or if you use the ... (rest) parameter.

The … (rest) parameter

function traceArgArray(x: int, ... args) 
{
for (var i:uint = 0; i < args.length; i++)
{
trace (args[i]);
}
}
traceArgArray(1, 2, 3);
// output:
// 2
// 3

Functions passed as arguments to another function are passed by reference and not by value.

When you pass a function as an argument, you use only the identifier and not the parentheses operator that you use to call the method.

In fact, every function has a read-only property named length that stores the number of parameters defined for the function.

Function scope

The same scope rules that apply to variable identifiers apply to function identifiers.

Any time a function begins execution, a number of objects and properties are created. First, a special object called an activation object is created that stores the parameters and any local variables or functions declared in the function body.You cannot access the activation object directly because it is an internal mechanism. Second, a scope chain is created that contains an ordered list of objects that Flash Player checks for identifier declarations. Every function that executes has a scope chain that is stored in an internal property. For a nested function, the scope chain starts with its own activation object, followed by its parent function’s activation object. The chain continues in this manner until it reaches the global object. The global object is created when an ActionScript program begins, and contains all global variables and functions.

A function closure is an object that contains a snapshot of a function and its lexical environment.

The fact that function closures retain the scope in which they were defined creates interesting results when a function is passed as an argument or a return value into a different scope.

Methods behave similarly in that they also retain information about the lexical environment in which they were created.

The main difference between a function closure and a bound method is that the value of the this keyword in a bound method always refers to the instance to which it was originally attached, whereas in a function closure the value of the this keyword can change.

原创粉丝点击