第八章 函数
函数是JavaScript的主要组成部分。通过函数我们可以更有效地编写程序,也更利于扩展。函数通过一个执行名称包含和对运算分组来帮助我们管理复杂的代码。我们已经通过p5.js中内置的函数ellipse或background了解了如何调用函数。我们甚至还声明了自己的函数,因为p5.js强制我们将代码放在两个函数声明中:setup和draw。如果我们想要创建自己的函数,遵循与这些函数相同的规则创建或声明即可。
创建函数
创建(或声明)函数,我们首先要使用function关键字,然后选择一个可以描述函数功能或目的函数名。参见示例8-1。
示例8-1. 创建一个函数
function functionName() {
// 函数体
}
紧接着函数名的是括号。如果想要创建一个可以接受用户输入的函数,就可以在括号内定义参数来作为占位符变量名来接收用户未来的输入。一会儿我们就会看到如何使用。
然后就是大括号。大括号内的内容可称为函数体。这里我们可以编写构成函数逻辑的代码。我们可以用括号内定义的变量名来使用参数,作为运算的一部分我们需要执行代码体之内的内容。
我们举个简单的例子。看到p5.js里有ellipse函数,但没有circle(正圆)函数了吗?这丝毫不是问题,因为我们可以通过向ellipse函数传入相同的宽和高来创建正圆。为减少使用的参数,假设我们要创建一个circle函数来接收3个参数,x和y是画圆的位置,然后还有一个圆的直径。
示例8-2展示了实现方法。括号内我们写下的变量名,来在函数最终调用时传入。称之为参数是因为它们参数化我们创建的操作的函数。我们在函数内使用这些参数来让用户控制函数的内部运行。
示例8-2. 声明circle函数
function circle(x, y, diameter) {
ellipse(x, y, diameter, diameter);
}
我们可以选择任何参数名,但通常应使用能清晰表达用途的名称。在我们的示例中,x, y和diameter都带有含义。
在定义该函数后,我们使用函数名及传入参数来进行调用。传入函数的值称为函数的参数。注意如果未按要求传入参数函数可能无法正常运行(示例8-3)。
示例8-3. 调用circle函数
circle(width/2, height/2, 100);
如果这些词让你感到困惑请不要太过担心。需要些时间来进行适应。函数的参数可看作用户在使用函数时最终传入的值。调用函数时传入的这些值就称为参数。
有了circle函数,就不需要再使用ellipse函数来画正圆了。我们仅需使用自己的函数来画这些正圆。通过自己实现circle函数,我们知道其实画这些圆的底层使用还是ellipse函数。但函数的好处在于我们无需知晓它的工作原理。我们只需使用函数,而无需了解如何实现。由创建p5.js 的那些高手实现的ellipse函数可能在其内部使用很多技术来画出一个圆,但我们所关心的只是调用它能画出圆形就好了。
本例中的画圆函数并没有为我们提高什么效率。事实上,我们可以向ellipse函数只传递3个参数来画正圆。但函数在构建更为复杂的程序时非常重要。通过在同一个可执行名称下包含或对运算分组来管理复杂性。函数基本上是一个黑盒子,里面包含相应的代码。此外,在函数中通过 var声明的变量在函数外部都不可见。这表示在函数外调用这些变量会产生报错。参见示例8-4。
示例8-4. 变量可见性(作用域)
function setup() {
createCanvas(800, 300);
sayHello();
}
function draw() {
background(220);
}
function sayHello(){
var message = 'Hello World!';
console.log(message);
}
console.log(message); // 本行将抛出报错
第15行的console.log函数将会抛出错误,因为变量message仅在函数sayHello中可见。
Uncaught ReferenceError: message is not defined
函数在无输入(参数)、单个输入或多个输入时都可以使用,也可以返回或不返回结果。下面就说明返回值的意思是什么。
假设我们要创建一个对给定数值相乘的函数,也即计算给定数字的平方值。示例8-5展示了实现的函数。它接收一个数字作为参数,并创建在屏幕上显示该数字的文本。我们使用函数可以在屏幕上显示数字的平方,所以它还是有些用处的。结果请见图8-1。
示例8-5. 创建相乘函数
function setup() {
createCanvas(800, 300);
}
function draw() {
background(1, 75, 100);
squared(10);
}
function squared(num){
fill(237, 34, 93);
textSize(60);
textAlign(CENTER, CENTER);
text(num * num, width/2, height/2);
}