第四课(续)

---《网猴》
无参数函数
该HTML页含有一个叫做announceTime的函数。从一个链接调用
annoumnceTime:


<a href="#" onClick="announceTime();">time!</a>



就象这样:

下行看起来就象第二课:


<a href="#" onClick="alert('Hello!');">Hello!</a>



这称为从一个链接调用警告对话框。函数就象一种方法,唯一不
同的是,方法依附于一个对象。在这个警告的例子中,这个对象
是一个窗口对象。

让我们回到函数本身。如果你看看源码,你将看到函数位于HTML
文件的头部中。


<html>

<head>

<title>Function with No Parameters</title>

<script langauge="JavaScript">

<!-- hide me

function announceTime()

{

//get the date, the hour, minutes, and seconds

var the_date = new Date();

var the_hour = the_date.getHours();

var the_minute = the_date.getMinutes();

var the_second = the_date.getSeconds();


//put together the string and alert with it

var the_time = the_hour + ":" + the_minute
+ ":" + the_second;

alert("The time is now: " + the_time);

}


// show me -->

</script>


</head>

<body>

...

</body>

</html>

好,让我们逐行复习这个函数。首先,所有函数来自于该种格式:


function functionName(parameter list)

{

statements ...

}



函数的命名规则于变量差不多。第一个字符必须是字母或一标准符
号。其余字符可为数字或一横线。但必须保证函数不于已定义的变
量同名。否则将出现很糟糕的结果。我是用内部大写的方式命名函
数以保证它们不与字符碰巧重名。

函数名后是一组参数。本例是无参数的函数,下一例中我们再举例
描述。

参数后是函数的主体。这是一组当函数调用后是想运行的语句。在
下面几个例子中,我打算利用这个报时器,所以让我描述一下它是
怎样工作的。

第一行:


var the_date = new Date();



取得一个新的日期对象。就象你在用数组时取得一个新的数组一
样,在你要找出即时是什么时间时你需要先取得一个日期对象。
当找到了一个新的日期对象,它自动重置到当前的日期和时间。
为了在对象以外得到这个信息,你必须使用这种对象方法:

这些方法从日期对象上取得了合适的数字。


var the_hour = the_date.getHours();

var the_minute = the_date.getMinutes();

var the_second = the_date.getSeconds();



你可能疑惑:我怎样能假定日期对象知道何种方式?甚或我如何
知道有这样一件事可作为日期对象?这些缘由应从Javascript
库中获取,我将尽我所能解释内置Javascript对象,但不一定能
彻底的使你清楚。

函数的其他部分就很清楚了。它以这种方式调用返回数字,把它
们变成字符串,并且调用警告方式以弹出一个字符串对话框。注
意你可以在函数内部调用一个方式和函数。我们将详尽讨论。

现在如果你也玩透了时间链接,你可能注意到了有些什么不对的
事。你每次可能会得到这样的反馈:“12:12:04”,这是
getSecond()将返回值为“4”。那么当你合成为时间时,你看到
的就是the_minute+“:”+the_second得到14:4而非是我们想要
的。解决它是个容易的事,需要个新的函数来修补分、秒合成值。

请看参数及返回值。

参数及返回值
尽管无参数的函数在减少写源码工作量,HTML源码可读性上很
有用,但有参数的函数会更为有用。

上一例中,当返回的分、秒值小于10时会有问题发生。我们想
要看到的秒值是04而非4。我们可以这样做:


var the_minute = the_date.getMinutes();

if (the_minute < 10)

{

the_minute = "0" + the_minute;

}



var the_second = the_date.getSeconds();

if (the_second < 10)

{

the_second = "0" + the_second;

}

它会非常有效。但是注意,同样的源码你写了两次:若某件
东西小于10,则前面加“0”。所以要考虑当用同一代码要多
次重写时,用函数来做。本例中我写了一个叫fixNumber的函数:


function fixNumber(the_number)

{

if (the_number < 10)

{

the_number = "0" + the_number;

}

return the_number;

}

fixNumber的参数是the_number。一个参数也是一个变量,当该
函数被调用时,其参数值也被设置。在本例中,我们这样调用
函数:


var fixed_variable = fixNumber(4);

参数the_number在函数中设置为4。到现在你应该对fixNumber
的主体有了一定的了解。它的意思是:如果变量the_number小
于10,则在它的前面加一个0。这里面新的内容是return指令:
返回the_number的值。在下面的情况中就会用到return指令:


var some_variable = someFunction();

变量some_variable的值是函数someFunction() 的返回值。
在fixNumber中,我加入: return the_number,则退出函数并
将返回the_number的值返回给任何一个等待被设置的变量。
所以,我这样书写代码:

var fixed_variable = fixNumber(4);


the_number的初始值将通过函数调用被设置为4,然后由于4小
于10,所以the_number将被改为"04"。然后the_number值被
返回,而且变量fixed_variable将被设置为"04" 。

为了将fixNumber包括在原始函数announceTime()中,我添加了
如下内容:

function announceTime()

{

//get the date, the hour, minutes, and seconds

var the_date = new Date();

var the_hour = the_date.getHours();

var the_minute = the_date.getMinutes();

var fixed_minute = fixNumber(the_minute);

var the_second = the_date.getSeconds();

var fixed_second = fixNumber(the_second);


//put together the string and alert with it

var the_time = the_hour + ":" + fixed_minute + ":" + fixed_second;

alert("The time is now: " +the_time);

}

假定时间链接被点击时,时间为12:04:05。用new Date()获得
日期,用getHours()获得小时,用前面所属方法获得分钟,分
钟在本例中应该是4, 然后调用fixNumber,其参数为the_minute:


var fixed_minute = fixNumber(the_minute);



当fixNumber()被调用时,参数the_number被设置为the_minute。
在本例中由于the_minute是4,所以the_number将被设置为4。
设置完参数后,我们进入函数主体。由于4小于10,the_number
被改变为"04",然后the_number值用return指令返回。当"04"
被fixNumber返回后,本例fixed_minute就等于"04"。

我们一步一步来研究该过程。假定时间为12:04:05。

我们从函数announceTime()开始
the_minute = the_date.getMinutes();则the_minute = 4
fixed_minute = fixNumber(the_minute);等于函
数fixNumber()并将其值返回给fixed_minute
现在进入函数fixNumber()
函数fixNumber(the_number)fixNumber()用the_minute的
值调用,the_minute值是4,所以现在the_number = 4
如果(the_number < 10) {the_number = "0" +
the_number;}由于4小于10,所以the_number现在等于"04"
返回the_number值,退出该函数并返回值"04"
现在已经退出函数fixTime(),所以现在我们回
到announceTime()

该函数返回值为"04",所以fixed_minute 现在等于"04"
该例用了一个只有一个参数的函数。实际上你可以为函数
设置多个参数。例如该函数输入两个数组并返回一个元素
列表。

多于一个参数的函数
这是我定义的一个数组:


var monkeys = new Array("mattmarg","wendy",
"kristin","tim","aaron", "luke");

var kittyphile = new Array("wendy", "ruby",
"roscoe", "tim");

var discophile = new Array("mattmarg",
"john travolta", "wendy");

var happy = new Array("tim", "wendy",
"stimpy", "aaron");

var cranky = new Array("ren", "mattmarg","luke");


 

随着这些数组的定义,arrayIntersect函数给出,我们可轻
而易举的发现那些网猴酷爱迪斯科:爱跳舞的网猴

注意到尽管John Travolta喜爱迪斯科,但他不在monkeys请
单中,则他就不是只爱跳舞的网猴为调用该函数值,可这么来:



<a href="#" onClick="arrayIntersect('dancing
monkeys',monkeys,discophile);">dancing monkeys</a>


 

这是个具有3个参数的函数:一个代表交叉的姓名,第一个数组,
及第二个数组。这也很容易发现爱猫的网猴名爱猫的网猴。

看一下源码:



<a href="#" onClick="arrayIntersect('monkeys who love
cats',monkeys,kittyphile);">cat-loving monkeys</a>


让我们看看arrayIntersect函数本身:


function arrayIntersect(intersect_name, array_1, array_2)

{

    var the_list = "";

    for (loop_1 = 0; loop_1 < array_1.length; loop_1++)

    {

        for (loop_2 = 0; loop_2 < array_2.length; loop_2++)

        {

            if (array_1[loop_1] == array_2[loop_2])

            {

                the_list = the_list + array_1[loop_1] + " ";

            }

        }

    }

    alert("the " + intersect_name + " are: "+ the_list);

}


看看你是否已经弄懂本例中的循环。关键是函数第一行:


function arrayIntersect(intersect_name, array_1, array_2)


这里定义了一个叫arrayIntersect的函数,它有3个参数。就象上
例,每个参数就象一个变量,当函数调用时赋值。因此,当函数被调
用时:



arrayIntersect('dancing monkeys',monkeys,discophile);


 

下列分配:

intersect_name = 'dancing monkeys'
array_1 = monkeys
array_2 = discophile
唯一需注意的是,你必须以正确的参数数目来调用函数。如果你一旦
象这样调用arrayIntersect:


arrayIntersect(monkeys,discophile);


 

将会出错。试一下看会发生什么错误。

在任一标准的Javascript程序中,函数都是基本的部件。因此理解其
工作原理极其重要。这里是一个测试你对这项工作理解多少的练习。
再综合地做一下本课中其它练习,再在你自己的浏览器中应用。