您的位置:首页 > 其它

(2012-01-08 旧博文搬运)[EssentialActionScript3.0中文版]无责任翻译-16章 作用域

2016-04-09 02:50 246 查看
刚接触as3的时候,边对着字典边翻译的,知识不足所以很多地方翻得不对,由于太懒现在也不打算再改了。。

Chapter 16. Scope

scope (作用域)是一个内有代码执行的程序的物理区域。在ActionScript 中有5种可能的作用域:

• 一个函数体

• 一个实例方法

• 一个静态方法体

• 一个类体

• 任何其他(i.e., global scope 全局作用域)

在程序执行中的任何指定的某一点,变量、函数、类、接口以及命名空间的有效性都由当前执行的代码的作用域管理。比如,在一个函数中的代码可以访问这个函数当地的变量,因为他在本函数作用域内执行代码。但是相对地,函数体之外的代码无法访问这个函数本地的变量因为它在函数作用域之外执行。

 

在ActionScript 中作用域之间可以套嵌。比如,一个函数可以被套嵌入一个实例方法中,而这个实例方法又被套嵌在一个类体中。

public class SomeClass {

public function someMethod ():void {

function someNestedFunction ():void {

// 该函数的作用域被嵌在someMethod()的作用域内部,

//someMethod()的作用域被又嵌在someClass的作用域内部

}

}

}

当一个作用域套嵌在另一个的内部,较大的作用域所具有的定义(变量、函数、类、接口、命名空间)会对被嵌入的作用域可用。比如,一个被嵌入实例方法的函数作用域可以访问这个方法本地的变量。围绕当前代码执行的整个的作用域套嵌列表被称为scopechain(作用域链)。

 

本章描述在ActionScript多种多样作用域中的变量、函数、类、接口、命名空间的有效性。

 

注意到除了定义以"accessible可访问"的形式在接下来的每一节列出的,一个外部包的公共定义也可以通过在给定作用域中使用 import 指令来使其可见。详细请看"ObjectCreation Example: Adding a Pet to the Zoo" in Chapter 1.

 

一个定义的位置和访问控制调节器2者结合来管理它在整个程序中的可访问性。作为参考, Table 16-1 列出了定义的可访问性,根据他们的位置和访问控制调节器。

 

Table 16-1. Definition accessibility by location andaccess-control modifier

 

Definition

Accessibility

在任何包的外部定义

只在包含它的源文件内可用

在未命名包内定义

整个程序可用

在已命名的包内定义public

在包含定义的包内以及任何import了它的地方可用

在已命名的包内定义internal

只在含定义的包内可用

Public方法或变量

任何地方,只要包含它的类可被访问

Internal方法或变量

包含它的类所在的包内可用

Protect方法或变量

包含它的类所在的包内以及继承该类的子类可用

Private方法或变量

仅包含它的类内可用

实例方法、静态方法或函数内的定义

方法函数体内以可用

 

 

16.1.全局作用域

直接放在一个包体外部或者包体顶级的代码具有全局作用域。换句话说:

package {

// 此处的代码处于全局作用域

}

//此处的代码也处于全局作用域

 

处于全局作用域的代码可以访问下面的定义:

• 定义在未命名包的顶端的变量、函数、类、接口、命名空间

• 定义在任何包的外部但是在同一源文件(.as)中的变量、函数、类、接口、命名空间

 

换句话说:

package {

// 此处的定义对所有处于全局作用域的代码都可访问

}

// 此处的定义对处于同一源文件的所有代码可访问

要注意放置在一个已命名的包体的顶级的代码页可以访问放置在该包顶端的定义。这些定义是可访问的,因为在一个已命名的包内, ActionScript 自动打开对应该包的命名空间(看Chapter 17)。换句话说:

package somePackage {

// 此处的定义自动对somePackage包内所有代码可访问

}

 

 

 

16.2. 类作用域

放置在一个类体的顶级的代码处于该类的作用域。换句话:

package {

public class SomeClass {

// 此处的代码处于someClass作用域

}

}

NOTE

要注意,放在类体顶级的代码是被包含在一个自动创建的静态方法之内的(即 class initializer), 它会当ActionScript 在运行时定义该类时执行。看Chapter 4的 "The Class Initializer" 。

通过作用域链,一个类作用域内的代码可以访问下面的定义:

• 所有处于全局作用域的代码的定义

此外, 在一个类作用域内的代码还可以访问下面的定义:

• 由该类定义的静态方法和静态属性

• 由该类的祖先类定义的静态方法和静态属性(比如超类、超超类等)

换句话说:

package {

public class SomeClass extends SomeParentClass {

// 此处的静态方法和属性可以在整个SomeClass内被访问

}

}

 

package {

public class SomeParentClass {

// 此处的静态方法和属性也可以在整个SomeClass内被访问

}

}

要记住即使一个类可以访问它的祖先的静态方法属性,静态方法属性也不会被继承。请看"StaticMethods and Static Variables Not Inherited" in Chapter6.

 

16.3. 静态方法作用域

放在一个静态方法体内的代码处于该方法的作用域,话句话说:

 package {

public class SomeClass {

public static function staticMeth () {

// 此处的代码处于 staticMeth 作用域

}

}

}

通过作用域链,处在一个静态方法作用域中的代码可以访问下面的定义:

•对所有处于全局作用域代码可访问的定义

•对所有处于包含该静态方法定义的类的作用域中的代码可访问的定义

此外,一个静态方法作用域中的代码还可以访问下面的定义:

• 所有本地变量,嵌入的函数以及在该静态方法中定义的命名空间,话句话说:

package {

public class SomeClass extends SomeParentClass {

public static function staticMeth () {

// 本地变量、嵌入的函数以及定义在此的命名空间对整个staticMeth可访问

}

}

}

 

16.4. 实例方法作用域

放在一个实例方法体重的代码处于该方法作用域。换句话说:package {

public class SomeClass {

public function instanceMeth () {

// 此处的代码处于 instanceMeth 作用域

}

}

}

通过作用域链,处在一个实例方法作用域中的代码可以访问下面的定义:

• 所有对全局作用域代码可访问的定义

• 所有对处于包含该实例方法定义的类的作用域中的代码可访问的定义

此外,在实例方法作用域中的代码还可以访问下面的定义:

 •在构造函数调用后的所有该对象的实例方法和变量(受到访问控制调节器强加的限制控制)

• 所有的本地变量、被嵌入的函数以及定义在该实例方法中的命名空间。

话句话说:

package {

public class SomeClass extends SomeParentClass {

public function instanceMeth () {

// 1) 所有当前对象(即this)的实例方法和属性都对整个instanceMeth()可访问

// (受到访问控制调节器强加的限制控制)

// 2) 本地属性、嵌入的函数以及定义在此的命名空间对整个instanceMeth()可访问}

}

}

 

 

16.5. 函数作用域

放在一个函数体内的代码处于函数作用域。这个处于函数作用域的特殊的由定义组成的列表取决于该函数在程序中的位置。

如果该函数定义在包级别或者任何包的外部,则它的代码可以访问下面的定义:

•所有对处于全局作用域代码可访问的定义

•所有本地属性、嵌入的函数和在本函数中定义的命名空间

 

在一个静态方法中的函数中的代码可以访问下面定义:

•所有对处于全局作用域代码可访问的定义

•所有对处于该静态方法作用域中的代码可访问的定义

•所有本地属性、嵌入的函数和在本函数中定义的命名空间

 

在一个实例方法中的函数中的代码可以访问下面定义:

•所有对处于全局作用域代码可访问的定义

•所有对处于该实例方法作用域中的代码可访问的定义

•所有本地属性、嵌入的函数和在本函数中定义的命名空间

 

一个函数在另一个函数中被定义,则该函数的代码可以访问下面的定义:

•所有对处于全局作用域代码可访问的定义

•所有对处于该围合函数中的代码可访问的定义

•所有本地属性、嵌入的函数和在该函数中定义的命名空间

 

 

16.6. 作用域总结

下面的代码总结了ActionScript 有效作用域:

package {

// 这里的代码在全局作用域内

public class SomeClass {

// 这里的代码在SomeClass作用域内

public static function staticMeth ():void {

// 这里的代码在staticMeth作用域内

}

public function instanceMeth ():void {

// 这里的代码在instanceMeth作用域内

function nestedFunc ():void {

// 这里的代码在nestedFunc作用域内

}

}

}

}

// 这里的代码在全局作用域内

 

 

16.7. 内部的细节

在内部, ActionScript 使用一个对象的清单来记录作用域链中的定义。对象们被用做保存定义在下面每个作用域中:

• 全局作用域: 全局对象 (一个被AS自动创建用于保持全局定义的对象)

• 类作用域: 类的Class 对象 (以及该类祖先的 Class对象)

• 静态方法作用域 : 类的 Class 对象(以及该类祖先的 Class 对象)

• 实例方法作用域 : 当前对象 (i.e., this)和一个activationobject (活动对象是一个被AS内部创建和储存用于维持本地变量和函数/方法参数的对象)

• 函数作用域: 一个活动对象

 

当ActionScript 在程序中遇到一个标识符表达式,他在作用域的对象之中搜寻这个标识符。比如,考虑下面的代码:

 

package {

public classSomeClass {

public functioninstanceMeth ():void {

functionnestedFunc ():void {

trace(a);

}

}

}

}

var a:int = 15;

在前面的代码中,当ActionScript 遇到标识符a,它开始在nestedFunc()'的活动对象中搜寻这个标识符的值。但是nestedFunc()'没有定义任何叫做a的变量或者属性,所以ActionScript接下来在当前对象(即调用了instanceMeth()的对象)搜寻a。但是SomeClass没有定义任何叫做a的实例属性或者实例方法。所以ActionScript下一步在
SomeClass的类对象中寻找a。但是SomeClass 没有定义任何叫做a的静态方法或者属性,所以ActionScript 下一步在
SomeClass的超类(Object)的对象中寻找a。但是Object也没有定义叫做a的静态方法或者静态属性,所以ActionScript 接下来在全局对象中寻找 a。于是它找到了a,并确定值为15.获得了a的值后, ActionScript 在调试中输出15。

 

这里是ActionScript 在其中寻找a的对象,按照被搜索的先后顺序:

• nestedFunc()'的活动对象

• 在内部调用 instanceMeth() 的对象

• SomeClass的类对象

• Object's的类对象t

• 全局对象

 

如果a也没有在全局对象中被寻找到,那么ActionScript 会报告一个错误的引用。注意在前面的例子中,a是在全局对象中被定义的,但是只在定义了a的源文件中科访问。

NOTE

在包外定义的变量仅仅对包含了该定义的源文件中可访问。

 

现在我们了解了作用域链,让我们来以一个对AS操作作用域链的唯一手段——with语句的快速浏览来结束本章。

 

 

16.8. 使用with语句来扩展作用域链

with 语句提供了一个便捷的途径来引用一个对象的变量和方法而不需反复指定对象名。with语句使用下面格式:

with (object) {

substatements

}

当一个标识符在一个使用了with 语句的代码块中执行, 为了寻找这个特定名字 object被检查

—早于剩余其他作用域链的检查.话句话说,。换句话说,with 临时添加一个object 到ActionScript内部作用域链的对象清单的末尾。比如,要引用内置Math 类的PI 属性,我们可以一般使用下面的代码

Math.PI;

但是使用 with 语句,我们可以不需要Math 类的引用直接使用 PI 属性。

with (Math) { // Execute state
aea8
ments in the context of Math

trace(PI); // Displays: 3.1459... (because PI is defined on Math)

}

一些开发者发现with 语句在当书写反复引用一个特定对象的属性和方法的代码时很方便。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: