JavaScript之 函数 篇(4)

本文深入探讨函数的概念、作用及分类,详解函数声明、执行、参数传递、作用域、变量提升、return语句和递归等内容,通过实例演示如何利用函数提高代码复用性和维护性。

为什么要使用函数,我们先来看一个例子:

如何实现:

白日依山尽

********************

黄河入海流

********************

欲穷千里目

********************

更上一层楼

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>
复制代码


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值