|
上一篇:学编程从Javascript开始(四)Javascript基础语法
函数是Javascript的重要概念,因此有必要专门讲解一下相关内容。
1、函数定义
函数定义,就是编写完成函数工作的代码。
//语法
function 函数名称(参数列表) {
//函数体
return 返回值;
}
function(中文:函数,方法)是关键字,表示函数定义开始,函数名称是Javascript的标识符,需要符号标识符的约束。参数列表不是必须的,函数是否需要参数要根据需求情况来确定。函数体是完成函数工作的代码块,如果函数不需要返回任何数据,函数体中也可以没有return(中文:返回)语句。
//函数定义示例,定义一个叫helloFunction的函数,该函数完成1+1的计算并将
function helloFunction() {
return 1 + 1;
}
//函数调用
let result = helloFunction();//调用函数helloFunction,并将结果返回
alert(result);//2
修改index.html源码如下:
<!DOCTYPE html>
<html lang=&#34;zh&#34;>
<head>
<meta charset=&#34;UTF-8&#34;>
<meta http-equiv=&#34;X-UA-Compatible&#34; content=&#34;IE=edge&#34;>
<meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;>
<title>Javascript语言基础</title>
</head>
<body>
<h1 style=&#34;text-align: center;&#34;>Javascript语言基础</h1>
</body>
<script type=&#34;text/javascript&#34;>
//函数定义示例,定义一个叫helloFunction的函数,该函数完成1+1的计算并将
function helloFunction() {
return 1 + 1; //调用时才执行函数体中的代码
}
//函数调用
let result = helloFunction();//调用函数helloFunction,并将结果返回
alert(result);//2
</script>
</html>本教程的示例代码都可以在这个index.html中运行测试。
//定义带2个参数的函数
function addFunction(number1, number2) {
return number1 + number2;
}
let result1 = addFunction(1, 2);//调用函数计算1 + 2
alert(result1);//3
alert(addFuncton(3, 3));//6
alert(addFuncton(3,3)):alert函数的参数时一个函数调用表达式,运行时先将3和3传递给addFuncton,然后将计算结果6作为参数传递给alert函数,最后提示6。
2、函数的参数与返回值
定义函数时,函数的参数不是必须的。例如:
function demoFunc() {
alert(&#34;这个函数没有参数定义&#34;);//没有return关键字,函数没有返回值
}
function demoFunc2(arg1, arg2) {
alert(&#34;这个函数有2个参数!&#34;);
return arg1 + arg2;
}
//函数调用
domoFunc();//没有返回值,没有赋值运算符=
let result = domoFunc2(1, 2); //1、2是调用时给函数参数赋值,1+2等于3,返回数字3
let result = domoFunc2(&#34;1&#34;, &#34;2&#34;); //1、2是调用时给函数参数赋值,字符串1+字符串2等于字符串12(字符串拼接),返回字符串12
3、函数调用
当Javascript解释器在运行Javascript程序时,遇到函数定义时只是检查函数定义是否合法,而不会执行函数。只有在解释到函数调用时才执行函数。
//关键字function开头,函数定义
function demoFunction() {
alert(&#34;demoFunction被调用&#34;);
}
//函数调用:函数名后面加()对,()对中有没有参数值列表由函数定义决定
demoFunction();
//函数调用
demoFunction2(123);
//函数定义
function demoFunction2(arg) {
alert(&#34;demoFunction2被调,参数arg的值是:&#34; + arg);
}
函数定义的位置可以出现在函数调用之后,这和变量的使用有点区别:变量是先声明,后使用。
4、用函数优化新版猜数游戏
新版猜数游戏,用一个函数完成了所有的代码。这个猜数游戏用一个函数完成所有的逻辑,而且这个函数看上去逻辑也不是很复杂,这是因为猜数游戏的逻辑本身不复杂。尽管不复杂,我们还是可以通过按照以下处理步骤定义主函数:
第一步:生成秘密数字;
第二步:获取用户输入;
第三步:比较用户输入数字与秘密数字;
然后通过重构主函数简化主程序逻辑代码:
<!DOCTYPE html>
<html lang=&#34;zh&#34;>
<head>
<meta charset=&#34;UTF-8&#34;>
<meta http-equiv=&#34;X-UA-Compatible&#34; content=&#34;IE=edge&#34;>
<meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;>
<title>猜数游戏V2</title>
</head>
<body>
<h1 style=&#34;text-align: center;&#34;>猜数游戏V2</h1>
<hr>
<input type=&#34;button&#34; value=&#34;开始猜数游戏&#34; onclick=&#34;startGuessGame();&#34;>
</body>
<script type=&#34;text/javascript&#34;>
//定义生成秘密数字的函数
function generateSecurityNumber() {
let secretNumber = Math.random();//生成随机数,并把随机数保存到一个叫做secretNumber的内存块中
secretNumber = secretNumber * 100;//用保存到名字为secretNumber的内存块中的值乘以100,然后保存
return Math.round(secretNumber);//数字值四舍五入,然后返回
}
//定义获取用户输入的函数
function getInputValue(msg) {
let inputValue = prompt(msg);//提示用户输入数据
return parseInt(inputValue);//将用户输入的数据返回
}
//判断用户输入数字与秘密数字的结果
function checkNumberOfInputToSecurityNumber(inputValue, secretNumber) {
while (inputValue != secretNumber) {
if (inputValue < secretNumber) {
inputValue = getInputValue(&#34;太小了,请重新输入:&#34;);
} else {
inputValue = getInputValue(&#34;太大了,请重新输入:&#34;);
}
}
alert(&#34;恭喜你,猜对了!&#34;);
}
//主逻辑代码清晰、简单
function startGuessGame() {
let secretNumber = generateSecurityNumber();//生成秘密数字
let inputValue = getInputValue(&#34;请输入0到100的数字:&#34;);//获取玩家输入
checkNumberOfInputToSecurityNumber(inputValue, secretNumber);//判断结果
}
</script>
</html>
经过重构,程序达到了相同的目的,但主函数startGuessGame的逻辑就变得清晰明了多了。这样的重构还有一个好处:就是当需求变更的时候,只要调整和需求相关的函数的代码就可以了。比如现在程序有一个问题:如果用户在提示玩家输入猜测的数字的时候,玩家点击了取消按钮或者输入的不是一个有效数字的情况下,程序逻辑是不完美。我们对程序稍微改动一下:当用户点击取消按钮或者输入不合法的情况下,要提示用户重新输入,修改后的函数定义如下:
//修改后的定义获取用户输入的函数
function getInputValue(msg) {
let rtnValue = -1;
let inputValue = prompt(msg);//提示用户输入数据
while (true) { //只有输入正确的数据后,才退出提示输入信息的循环语句
if (inputValue != null && inputValue.trim() != &#34;&#34;) {
//点击确定且输入了数据
try {
rtnValue = parseInt(inputValue);//输入非数字字符后,parseInt函数会报错,也就是转入catch块执行
break;//输入一切正常后,则退出循环,如果输入非数字字符,则不会执行这里的break
} catch (error) {
//输入非数字时会出错
inputValue = prompt(msg);
}
} else {
//点击取消按钮或点击确定但没有输入数据,继续提示
inputValue = prompt(msg);
}
}
return rtnValue;//将用户输入的数据返回
}
这里利用了try-catch语句来做合法性的数据校验,其实还可以用正则表达式对数据合法性进行校验,但这是另外一个话题,留到后续介绍。try-catch语句是Javascript的错误处理形式的代码,有两种语法形式,具体解释如下:
//形式一
try {
//正常执行代码,如果代码发生异常,则立即转入catch块,异常位置后的代码不会执行
} catch (error) {
//正常执行代码块中的代码如果发生错误则立即转到这里开始执行
}
//形式二
try {
//正常执行代码块,如果代码发生异常,则立即转入
} catch (error) {
//正常执行代码块中的代码如果发生错误则立即转到这里开始执行
} finally {
//finally块中的代码是无论正常执行代码块中的代码在执行过程中是否发生异常都会被执行
//如果正常执行代码块中的代码在执行过程中发生异常,则先执行catch块中的代码,然后在执行finally块块中的代码
}
这里点击取消按钮,要求玩家继续输入数字,也就是说程序要求玩家必须完成这次猜数游戏,否则一直提示需要输入数据。玩家点击取消实际上是不想玩猜数游戏了,还逼玩家继续玩下去,感觉这种处理方式有些霸凌的感觉。于是我们的需求变成了:点击取消按钮,实际是玩家放弃了这轮游戏,我们该如何修改程序呢?
实现逻辑调整一下:如果玩家点击了取消,我们可以让函数getInputValue返回一个特征值例如null,然后在判断输入数据的时候发现玩家输入函数返回了null,则不再继续猜数。修改后的代码如下:
<!DOCTYPE html>
<html lang=&#34;zh&#34;>
<head>
<meta charset=&#34;UTF-8&#34;>
<meta http-equiv=&#34;X-UA-Compatible&#34; content=&#34;IE=edge&#34;>
<meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;>
<title>猜数游戏V2</title>
</head>
<body>
<h1 style=&#34;text-align: center;&#34;>猜数游戏V2</h1>
<hr>
<input type=&#34;button&#34; value=&#34;开始猜数游戏&#34; onclick=&#34;startGuessGame();&#34;>
</body>
<script type=&#34;text/javascript&#34;>
//定义生成秘密数字的函数
function generateSecurityNumber() {
let secretNumber = Math.random();//生成随机数,并把随机数保存到一个叫做secretNumber的内存块中
secretNumber = secretNumber * 100;//用保存到名字为secretNumber的内存块中的值乘以100,然后保存
return Math.round(secretNumber);//数字值四舍五入,然后返回值
}
//定义获取用户输入的函数
function getInputValue(msg) {
let rtnValue = -1;
let inputValue = prompt(msg);//提示用户输入数据
while (true) { //只有输入正确的数据后,才退出提示输入信息的循环语句
if (inputValue != null && inputValue.trim() != &#34;&#34;) {
//点击确定且输入了数据
try {
rtnValue = parseInt(inputValue);//输入非数字字符后,parseInt函数会报错,也就是转入catch块执行
break;//输入一切正常后,则退出循环
} catch (error) {
//输入非数字时会出错
inputValue = prompt(msg);
}
} else if (inputValue == null) {
//点击取消按钮
rtnValue = null;
break;//跳出循环
} else {
//点击确定但没有输入数据,继续提示
inputValue = prompt(msg);
}
}
return rtnValue;//将用户输入的数据返回
}
//判断用户输入数字与秘密数字的结果
function checkNumberOfInputToSecurityNumber(inputValue, secretNumber) {
while (inputValue != null && inputValue != secretNumber) { //点击确定按钮且输入数字和秘密数字不同
if (inputValue < secretNumber) {
inputValue = getInputValue(&#34;太小了,请重新输入:&#34;);
} else {
inputValue = getInputValue(&#34;太大了,请重新输入:&#34;);
}
}
if (inputValue != null) {//点击确定按钮且输入数字和秘密数字相同
alert(&#34;恭喜你,猜对了!&#34;);
}
}
function startGuessGame() {
let secretNumber = generateSecurityNumber();//用保存到名字为secretNumber的内存块中的值四舍五入,然后保存
let inputValue = getInputValue(&#34;请输入0到100的数字:&#34;);//获取玩家输入的字符串
checkNumberOfInputToSecurityNumber(inputValue, secretNumber);
}
</script>
</html>
最终的程序就演变成了目前这个状态,这些演变都是根据需求一步步演变过来的,如果不定义函数,所有代码都集中在startGuessGame函数中,可以想象一下这个程序有多难维护。
下一篇:学编程从Javascript开始(六)用Javascript编写用户界面程序 |
|