和在 Java 中一样,一个方法涉及变量的值以及封闭范围中的方法名。(在 Java 中,“封闭范围”会是一个类)。
示例代码
- a = 1;
- anotherMethod() { ... }
- foo() {
- print( a );
- a = a+1;
- anotherMethod();
- }
- // 调用 foo()
- foo(); // 打印 1
- print( a ); // 打印 2
运行效果
通常情况下变量和方法“继承”自他们的父范围。在上面的例子中有两个级别的范围:最顶层的或者“全局的”范围以及方法“foo()”的范围。之后我们会讨论 BeanShell 中的脚本对象,你将会看到涉及到的范围可以是任意级别的。但是规则是相似的。
在 Java 中,一个带类型的变量在声明它的范围之外是不可见的。因此,声明一个带类型的变量可以限制它的范围或者是其成为局部变量。在 BeanShell 中使用非类型化的或者“松散”类型的变量也就相当于声明了一个局部变量。就是说,如果你在哪里使用了一个未定义的变量,那么它默认为本地作用域。
示例代码
- a = 1;
- foo() {
- a = a + 1; // a 定义在父范围中
- b = 3; // 未定义, 默认为本地作用域
- int c = 4; // 声明为本地作用域
- }
- // 调用 foo()
- foo();
- print( a ); // 打印 2
- print( b ); // ERROR! b 未定义
- print( c ); // ERROR! c 未定义
运行效果
在上面的例子中变量“a”被定义在全局的范围内。当它的值被读取并在foo()方法里分配了值,“a”的总值就会受到影响。
变量“b”是一个非类型的变量用法。既然“b”没有被定义而且也没有在任何封闭范围内被赋值,那么它就成为foo范围中的本地变量“b”。变量“c”(带类型)明确地被定义在foo()范围里,因此它当然是foo()的本地变量。
稍后我们将看到 BeanShell 方法可以任意嵌套。如果我们在foo()方法里声明另一个方法,可以看到所有这些变量(a,b和c)同样地也在foo()范围中。
宽松的类型变量的作用域
和 Java 中一样,声明了一个带类型的变量就是将它本地化。即使变量存在于外部范围,它也会被本地变量声明所隐藏。那么宽松的类型变量又是怎样的?就如同我们看到的 那样,非类型的变量用法看起来就像一个普通的 Java 变量分配。如果我们希望一个和全局变量有同样名称的变量本地化该怎么做?一种回答就是凭借声明变量类型。但是如果我们希望继续在这种情况下使用宽松的类型 变量有两种选择:我们可以通过 BeanShell 的类型“var”明确地声明一个宽松的类型变量。或者我们可以简单地通过修饰符“this.”来进行赋值。
如果你希望这么做,你可以明确地使用特殊类型“var”声明一个非类型变量。
示例代码
- foo() {
- var a = 1;
- }
- foo();
- print( a ); // ERROR! a 未定义!
运行效果
在 BeanShell 中“var”是一个神奇的类型,代表了一个宽松(未定义类型)的变量。一个声明了“var”的变量的默认值为null。
换一种方式,你可以使用作用域修饰符“this”来明确地使变量得以赋值并将它本地化。
示例代码
- foo() {
- this.a = 1;
- }
- foo();
- print( a ); // ERROR! a 未定义!
运行效果
在这个例子中,我们使用了修饰符“this”来是给予非类型变量的范围并使其本地化。我们会在后面章节中的脚本对象中解释“this”以及它在 BeanShell 脚本方法中得意义。
相关内容见《BeanShell变量的基本范围》。
本文转自 tongqiuyan 51CTO博客,原文链接:http://blog.51cto.com/tongqiuyan/755352