当前位置: 首页 > 文档资料 > TJS2 参考手册 >

函数

优质
小牛编辑
134浏览
2023-12-01

 TJS2 的函数和 子程序 大致上相同。即使没有返回值也会被作为函数来处理。
 作为类或对象的成员的函数又被称为“方法”。

函数的书写方式

 函数可以依照下面这样的格式来书写。

function函数名(参数列表)
{
函数的内容
}

 首先,定义函数需要写下 function 关键字。然后在关键字后面写函数名。以后这个函数就用这个函数名来调用。
 函数的内容里可以写上想要在函数中执行的语句和代码段。

例:
functiontest(a){System.inform(a);}
functionfunc(a,b,c,d)
{
test(a);
test(b);
test(c);
test(d);
returna+b-c*d;
}

对函数使用 instanceof 运算符和 "Function" 操作数的话,会返回真(按照上面的例子来说,func instanceof "Function" 为真)。

函数的调用

 函数使用 ( ) 运算符来调用,就象下面这样写。
函数名( 参数 )
没有参数的时候就写成 函数名( ) 。将复数的表达式指定为参数的时候应该用逗号分隔。

例:
func();
func(1+2,1-2);
func(func2());

还有,没有指定表达式而空着的参数,会被看作指定了 void 。

例:
func(,1);//会被当作指定了void,1
func(,);//会被当作指定了void,void

参数列表

 参数列表是那些用来接受传入的参数的变量的名字。函数被调用时传入的参数会按照参数列表中的顺序传递给各个变量。

例:
functiontest(a,b,c)
{
//这个时候就能使用a和b和c这3个变量了,
//传入的3个参数被代入到这3个变量中了。
//像test(1,2,3)这样调用的话,a中会被代入1,
//b中会被代入2,c中会被代入3。
}

 这些参数都全局变量,在函数执行结束后这些参数就不能用了。

 在 TJS2 中,调用函数时提供的参数比函数定义的参数少或者多的话,是不会产生错误的。 ( 如果那个函数不是由TJS2写成的 ( 那函数的实体是由 C++ 等语言写成的 ) 就会产生错误,这是个例外 )。提供的参数比声明时多的话,多出的部分会被忽略,如果少的话,接收不到参数的变量会被传入 void 。

例:
functiontest(a,b)
{
//如果像test(1)这样调用,a中会被代入1,b中会被代入void。
//如果像test(1,2,3)这样调用,a中会被代入1,b中会被代入2,3会被忽略
}

 参数列表中的各个参数可以在后面用 = 连接来指定默认值 ( 默认值参数 ) 。当某个参数被指定为 void 或者提供的参数比声明时的参数少时,会自动将默认值指定给对应的参数。

例:
functiontest(a=-1,b=1)
{
//如果……
//像test()这样调用的话,a=-1,b=1
//像test(5)这样调用的话,a=5,b=1
//像test(void,void)这样调用的话,a=-1,b=1
//像test(,4)这样调用的话,a=-1,b=4
}

 不需要接受参数的函数可以省略(不写)参数列表。

例:
functiontest
{
//不接受参数的函数
}

表达式声明函数

 在表达式中使用 function 可以定义没有名字的函数,也就是 表达式声明函数 ( 匿名函数 ) 。
 在这种情况下会省略函数的名字。

例:
varfunc=function(i){returni*5;};
varfunc2=function{System.inform("hoge");};
varv=func();//调用func函数
func2();//调用func2函数

参数的省略

 调用函数的时候将 ... 作为参数,就可以把函数调用表达式所在的函数所接受的参数照原样传入到被调用的函数中。即使参数的值被改变了,或者或者接受的参数数量不足,也会以那些参数传入时的内容和数量传给被调用的函数。

例:
functiontest2(a,b)
{
//函数的内容
}

functiontest()
{
test2(...);
//将传给test的参数,以参数传入时的内容和数量传给test2
}

test(1,2);
//因为test函数没有参数列表,1和2这两个参数在传入test函数后会被忽略,
//但是,在test中被调用的test2函数仍然会接收到这两个参数。

functiontest1(a,b=2)
{
test2(...);
//将传给test1的参数,以参数传入时的内容和数量传给test2
}

test1(1);
//在参数1被传入test1之后,因为参数数量不足,默认值2会被代入到b中,
//但是,在test1中被调用的test2函数只会接收到1个参数,就是1,
//而不会接收到那个默认值2,因为那不是调用函数时传入的参数。


 译者注:为了更好的说明问题,对上面的事例作了一些修改。

参数向数组的转换

 可以把参数转化为数组传入函数中。声明函数时将 '*'加到参数名后面,就可以将传入的参数转化为数组。

例:
functionfunc(args*)
{
//args就是将传入这个函数的参数作为元素的数组
//也就是说,像func(1,2,3,4)这样调用的话,
//会按照1234的顺序将4个参数作为元素装入args中。
}

 也可以从参数列表的中间开始将后面的所有参数转化为数组传入。如果参数的数量不足,传入的数组可能是空的。

例:
functionfunc(x,args*)
{
//也就是说,像func(1,2,3,4)这样调用的话,
//x中会被代入1。然后,234这三个值会依次装入args。
//像func(1)这样调用的话,因为参数数量不足,
//args中就是空的了。
}


 这一点在处理参数数量不确定的情况时会很方便。

 那个将接受的参数转为数组的参数名可以不写,只写一个 * 。这种情况下,在下面提到的 数组参数的展开 时就可以使用没有名字的 * 。

数组参数的展开

 可以将接受的数组展开,将里面的元素当作参数传到函数中。这种情况下,和 参数向数组的转换 一样,调用函数时在想要展开的参数表达式后面添加 '*'就行了。指定了 '*'的想要展开的表达式的结果必须是数组。

例:
varargs=[1,2,3,4];
func(args*);
//args中包含1234这4个元素,
//所以上面的调用和func(1,2,3,4);具有相同效果。
func(0,args*,5);
//像这样把数组夹在其他参数的中间也是可以的。
//这样和func(0,1,2,3,4,5);具有相同效果。

 不指定表达式,只写一个 * 当作参数的话,就可以将这个函数被调用的表达式所在的函数在声明时包含的没有名字的 '*'参数传递到这个函数的 * 参数中。

例:
functionfunc(func_array,*)
{
//经由func_array参数传入的函数数组中的函数,
//会按照他们在func_array数组中的位置顺序依次被调用,
//传入func的第二个以及之后的参数在各个函数被调用时
//也会以传进来时的状态传入这些函数。
for(vari=0;i<func_array.count;i++)
func_array[i](i,*);
}

 使用没有名字的 * 定义的函数在调用时会比使用有名字的数组参数的函数效率更高。

例:
functionfunc(ar*){func2(ar*);}
functionfunc(*){func2(*);}
//上面的两个函数的作用是完全一样的,但是下面的那个效率更高

 没有名字的 * 和“参数的省略”具有相同效果。以下的两个函数声明的效果是一样的。

例:
functionfunc(){func2(...);}
functionfunc(*){func2(*);}