为什么要使用函数,我们先来看一个例子:
如何实现:
白日依山尽
********************
黄河入海流
********************
欲穷千里目
********************
更上一层楼
document.write("<h1>白日依山尽</h1>");
for(var n=0;n<20;n++){
document.write("*");
}
document.write("<h1>黄河入海流</h1>");
for(n=0;n<20;n++){
console.log("*");
}
document.write("<h1>欲穷千里目</h1>");
for(n=0;n<20;n++){
console.log("*");
}
document.write("<h1>更上一层楼</h1>");复制代码
上述代码虽然可以实现题目的要求,但是存在许多问题:
代码冗余,可读性差,编写量大,维护性差,拷贝容易,修改难;
如何解决上述的问题:将代码管理,使用的时候,直接拿来使用即可,就需要使用函数。
下边来定义一个函数:
function text(){ //定义了一个名叫text的函数
for(n=0;n<24;n++){
document.write("*");
}
}
document.write("<h1>白日依山尽</h1>");
text();//调用函数 函数名()
document.write("<h1>黄河入海流</h1>");
text();
document.write("<h1>欲穷千里目</h1>");
text();
document.write("<h1>更上一层楼</h1>");
text();
复制代码
1.函数的概念及其作用。
1.1 概念: 函数是由一系列语句构成的代码块,主要用于完成特定的功能。如果把函数比作一台机器的话,那么每个机器的作用各不相同,比如,爆米花机器,放入玉米出来的是爆米花。
1.2 作用: 函数需要的作用是为了方便编程,提高程序的重复利用率;方便调试程序,方便维护。一个功能,可以分解成若干的函数,提高程序的开发效率以及程序代码的利用率。
简单地说:把重复使用的代码封装到函数(方法)里(封装的代码块), 需要的时候再调用,可以只定义函数不调用,但是不能只调用而没有定义。
注意:函数的定义有默认提升功能。
2. 函数的分类
2.1 系统函数
常用的系统函数:alert() console.log() parseInt(), parseIntFloat()保留小数, isNaN(s)函数 ,eval()函数等等。
- parseInt()函数将字符串转化为整数,他从字符串的开头开始解析,在第一个非整数位停止解析,并且返回前面读到的所有整数,如果字符串不已整数开头,将返回NaN(Not a Number:非数字值)。
- isNaN判断是否NaN(不是数字),如果该字符里不是全数字,则返回true;如果是全数字,则返回false。
- eval()函数 该函数用于计算并返回字符串表达式的值。
应用实例:
有时候我们通过ajax从后台获取的是一个json字符串,如果想要将其转换为json对象,这里可以用到js的eval()函数。
var data = "{ root:[{name:'1',value:'0'}]}";
var dataobj = eval("(" + data + ")");复制代码
2.2 自定义函数
3. 函数的声明和执行
- 函数的声明:函数只有声明之后才能够被使用
function 函数名 (参数列表) {
//函数体
} 复制代码
- 执行函数:
函数名(参数列表); //参数列表使用,分隔
具体实现函数:
4.参数
函数运行的时候,有时需要提供外部数据,不同的外部数据会得到不同的结果,这种外部数据就叫参数。
无参函数:就是没有参数的函数,
function 函数名(){
封装的代码
}复制代码
有参数的函数
需求:每次循环的次数有调用者决定。
function 函数名(函数1,函数2,函数3......){
执行的代码块
} 复制代码
为什么要传入参数呢? 这是为了让函数和开发者之间有交互。
function text(num,x){//形式参数:放到函数定义位置时
console.log(num);
console.log(x);
}
text(10,30);//实际参数:实际传入函数的参数;复制代码
关于函数的形式参数和实际参数
(1) 形式参数---就是在函数定义时,函数名后面的参数,不能用var修饰;
实际参数---就是调用时,函数名后面的参数。
(2) 传参就是赋值,将实参的值赋值给形参。
(3) JavaScript语言的特殊之处:不检查实参的类型,不检测形参的个数
JavaScript语言与大多数语言在函数参数上有所不同。JavaScript语言不在乎你传入的参数有多少个,不在乎参数的类型。
(4) javaScript语言中可以传入任意多个参数
还是开头那个例子,现在要求每一行的星号逐渐递增,如下代码:
function text(num){
for(var n=0;n<num;n++){
document.write("*");
}
}
document.write("<h1>白日依山尽</h1>");
text(20);
document.write("<h1>黄河入海流</h1>");
text(22);
document.write("<h1>欲穷千里目</h1>");
text(24);
document.write("<h1>更上一层楼</h1>");
text(26);复制代码
5. 函数的作用域
5.1 定义:作用域(scope)指的是变量存在的范围。在 ES5 的规范中,Javascript 只有两种作用域:一种是全局作用域,变量在整个程序中一直存在,所有地方都可以读取;另一种是函数作用域,变量只在函数内部存在。ES6 又新增了块级作用域,本文不涉及。
- 函数外部声明的变量就是全局变量(global variable),它可以在函数内部读取。
var x=10;
function fun(){
console,log(x);
}
fun(); // 10复制代码
上面的代码表明,函数fun
内部可以读取全局变量x
。
- 在函数内部定义的变量,外部无法读取,称为“局部变量”(local variable)。函数运行之后自动销毁。局部变量的优先级大于全局变量。
function fun(){
var x=10;
}
console.log(x);// ReferenceError: x is not defined复制代码
上面代码中,变量x
在函数内部定义,所以是一个局部变量,函数之外就无法读取。
函数内部定义的变量,会在该作用域内覆盖同名全局变量。
var x=10;
function fun(){
var x=30;
console.log(x);
}
fun();//30
console.log(x);//10
复制代码
上面代码中,变量x
同时在函数的外部和内部有定义。结果,在函数内部定义,局部变量x
覆盖了全局变量x
。
注意,对于var
命令来说,局部变量只能在函数内部声明,在其他区块中声明,一律都是全局变量。
if (true){
var x=10;
}
console.log(x);//10复制代码
上面代码中,变量x
在条件判断区块之中声明,结果就是一个全局变量,可以在区块之外读取。
不用var 定义变量时,会默认为是全局变量(不规范,不推荐)
function aaa(){
a=10;
}
aaa();
alert(a);复制代码
function aaa(){
var a=b=10;//a是局部变量,b是全局变量。
}
aaa();
console.log(a);
console.log(b);
复制代码
5.2 函数的变量提升
与全局作用域一样,函数作用域内部也会产生“变量提升”现象。var
命令声明的变量,不管在什么位置,变量声明都会被提升到函数体的头部。
function fun(x){
if (x>100){
var tmp=x-100;
}
}
//等同于
function fun(x){
var tmp;
if(x>100){
tmp=x-100;
}
}复制代码
console.log(x);//ReferenceError: x is not defined.复制代码
console.log(x);//undefined.
var x="10";//JS定义变量时,会把定义提升,然后在指定的位置赋值。复制代码
var a=20;
function aaa(a){//形式参数的优先级高于变量的定义(定义的变量);
console.log(a);
var a=20;
}
aaa(a);//20
复制代码
函数的定义,也有默认提升功能,会被提升到顶部;
var a=1;
console.log("1:"+a);//函数的定义:默认提升功能,如果出现同名函数,后边的函数覆盖前面的函数;
如果函数和变量重名,函数会被变量覆盖;
console.log("2"+a);
function a(){
alert(2);
}
console.log("3"+a);
var a=3;
console.log("4"+a);
function a(){
alert(3);
}
console.log("5"+a);
console.log("6:"+a());
复制代码
6.return语句的使用和递归
6.1函数体内部的return
语句,表示返回。JavaScript 引擎遇到return
语句,就直接返回return
后面的那个表达式的值,后面即使还有语句,也不会得到执行。也就是说,return
语句所带的那个表达式,就是函数的返回值。return
语句不是必需的,如果没有的话,该函数就不返回任何值,或者说返回undefined
。
function fn1(x,y){
var sum=0;
for(var n=x;n<=y;n++){
sum+=n;
}
return sum;//返回值 为了方便用这个值
}
var x=fn1(1,100);//当函数运行完之后,等于一个值;
var x=fn1(2,400);
console.log(x);
console.log(typeof(x));
//第二个作用:函数见到return会自动终止函数;
复制代码
6.2递归 函数可以调用自身,这就是递归(recursion)。下面就是通过递归,计算斐波那契数列的代码。
function fun(n){
if (n==0) {
return 0;
}
if (n==1) {
return 1;
}
return fun(n-1)+fun(n-2);
}
var x=fun(35);
console.log(x);
复制代码
//递归的使用,如果使用不当,会出现灾难性问题,递归必须要含有一个终止条件(明确的返回值)。
//100+fun1(99)=100+99+fun1(98)......
function fun1(n){
if (n==1) {
return 1;//当n=1的时候,直接返回就可以;
}
return n+fun1(n-1);
}
var x=fun1(100);
console.log(x);
复制代码
练习题:
1.求和的函数
<script>
function text(x,y){
var sum=0;
for(n=x;n<=y;n++){
sum+=n;
}
document.write(sum+"<br>");
}
text(1,10);
text(2.,30);
text(1,99);
</script>
复制代码
2.输出一个表格
<script>
function showTable(row,col,color){
document.write("<table border='1' cellspacing='0' bgcolor="+color+">");
for(j=0;j<row;j++){
document.write("<tr>");
for(n=0;n<col;n++){
document.write("<td>123</td>");
}
document.write("</tr>");
}
document.write("</table>");
}
showTable(3,3,"red");
showTable(6,6,"blue");
showTable(3,2,"pink");
</script>
复制代码
3.求任意三个数的最大值
<script>
function text(x,y,z){
if (x>y) {
if (x>z) {
console.log(x);
}else{
console.log(z);
}
}else{
if (y>z) {
console.log(y);
}else{
console.log(z)
}
}
}
text(10,23,78);
text(456,564,5656);
</script>
复制代码
4.统计每个字符的出现次数,并且找到出现次数最多的字符,都在控制台输出;
这是将其封装成了一个函数,可以计算出任意一段字符中哥哥字符出现的次数。
<script>//统计每个字符出现的次数,在控制台输出,并且把出现次数最多的字符在控制台输出;
拆分需求:1.含有多少个字符;
var str="adfeljorigfjewiofhfuoidaaaa";
var str1="adfuryeiu";
var a="jfeiowurfpwruijpc3m923-084r3209";
function text(str){
var arr=[];
for(var n=0;n<str.length;n++){
if (arr.indexOf(str.charAt(n))==-1) {
arr.push(str.charAt(n));
}
}
//2.统计每个字符出现的次数;
var sumarr=[];
for(var i=0;i<arr.length;i++){
var sum=0;
for(var j=0;j<str.length;j++){
if (str.charAt(j)==arr[i]) {
sum++;
}
}
sumarr.push(sum);
console.log(arr[i]+"出现的次数为"+sum);
}
console.log(arr);
console.log(sumarr);
//3.进行比较,在控制台输出:谁的出现次数最多,有多少次;
var max=sumarr[0];
var index=0;
for(var e=1;e<sumarr.length;e++){
if (sumarr[e]>max) {
max=sumarr[e];
index=e;
}
}
console.log(arr[index]+"出现的次数最多"+",为"+sumarr[index]+"次");
}
text(str);
text(str1);
text(a);
</script>
复制代码