函数
函数作用:将代码存入变量中,实现代码复用
1.1-函数介绍
-
函数是一种结构,使用function关键字声明
-
函数不会自动运行
-
函数定义后,需要主动调用才会触发
//1.声明函数:将代码存入结构中
function 函数名(){
函数体:一段代码
}//2.调用函数:执行函数体代码
函数名();
<script>
/*1.函数与循环区别:本质区别
a.作用不同:
循环:一段代码在一个地方执行多次(主动运行)
函数:一段代码在多个地方执行一次(被动运行)
b.本质不同
循环:只是一种语法,让代码重复执行
函数:是一种数据类型,存储的是代码
*/
/*2.什么样的代码需要使用函数
a.这段代码需要在多个地方执行
b.这段代码通常都是完成一个独立的小功能
*/
/*3.语法误区:函数语法就两个(声明与调用)
1.声明函数: function 函数名(){ 函数体代码 }
2.调用函数: 函数名()
3.变量取值: 函数名 (不会执行函数体代码,只是以字符串形式将变量中存储的东西打印出来而已)
*/
//需求 : 一段代码 需要在多个地方执行
//复制粘贴弊端 : (1)代码冗余 (2)不便于维护
/*
1.函数作用 : 实现某个功能代码的重复利用
2.函数语法
a. 声明函数 : ( *** 函数体代码不会执行 ***)
function 函数名(){
函数体 :一段代码
};
b. 调用函数 : 执行函数体代码
函数名();
*/
//(1)声明函数:打印99乘法表
function getChengFa() {
//定义一个变量,保存即将产生的字符串(实用,后面return讲)
let chengfaStr = '';
//外层循环:控制层数
for (let i = 1; i <= 9; i++) {
//内存循环:控制列数
for (let j = 1; j <= i; j++) {
//拼接内容
chengfaStr += `${j} * ${i} = ${j * i}  `;
}
//换行
chengfaStr += '<br>';
}
//返回结果
document.write(chengfaStr);
}
//(2)调用函数 : 执行函数体代码
getChengFa();
console.log('99乘法表,我的最爱');
//(3)既然这么爱,那就再来一次
getChengFa();
console.log('不爱了,吐了');
/*
3.函数注意点
a.以后什么样的代码你会放入函数中?
(1)多个地方执行
(2)独立的小功能
b.函数与循环 有着本质的区别
(1)本质区别
函数 :是一种数据类型,存储代码
循环 :是一种语法,重复执行代码
(2)作用不同
函数 : 一段代码在多个地方执行一次
循环 : 一段代码在一个地方执行多次
*/
</script>
1.2-函数参数
- 参数的目的是让函数能够变的灵活,可以完成不同的,但是功能类似的需求
- 函数参数分为两种:
- 形参:定义函数时的参数,属于占座位
- 实参:调用函数时的参数,属于实际数据
- 函数不会自动运行:所以先占位;调用时就是要实际运行,所以给数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*
1.函数作用 : 实现某个功能代码的重复利用
2.参数
2.1 参数作用 : 调用者 传递数据 给函数
2.2 语法
传 : 调用者
函数名(实参:实际参数)
收 : 函数
function 函数名(形参:形式参数){ 函数体代码 }
2.3 函数传参的本质 : 实参给形参赋值
* 实参和形参数量可以不一致,但是按照顺序赋值
*/
// 2.利用函数实现指定层数的乘法表
/**
* @description: 得到指定层数的乘法表
* @param {number} level:层数
* @return: 产生的字符串
*/
function getChengFa(level) { // level = 9
//定义一个变量,保存即将产生的字符串
let chengfaStr = '';
//外层循环:控制层数
for (let i = 1; i <= level; i++) {
//内存循环:控制列数
for (let j = 1; j <= i; j++) {
//拼接内容
chengfaStr += `${j} * ${i} = ${j * i}  `;
}
//换行
chengfaStr += '<br>';
}
//返回结果
document.write(chengfaStr);
}
//用户输入层数
let level = +prompt('请输入一个要打印的乘法表的层数:');
// 调用函数
getChengFa(level);
</script>
</body>
</html>
1.3-函数返回值
- 返回值是函数运行后的结果处理方式
- 实际开发过程中,不会在函数内部进行输出,都是把结果返回给调用者
- 函数不对结果负责:函数只负责做,至于做出来是否合适不管
- return关键字
- JS函数可以没有返回值
- 可以使用return返回任意类型数据
- return会终止函数的继续执行(结束函数运行)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*
1.函数作用 : 将代码存入变量中,可以实现代码的复用
2.返回值
2.1 返回值 : 函数 传递数据 给调用者
2.2 语法
传 : 函数
function 函数名(形参){ return 值; }
收 : 调用者
let 变量名 = 函数名()
*/
//求任意两个数字的和
function getSum(a,b){
let sum = a+b;
console.log(sum);
return sum;
console.log('1111');//不会执行
};
//将函数调用结果显示到页面
// 函数外部 无法直接 获取函数内部的变量
//console.log(sum);
/*函数调用工作流程 : 固定三个步骤
1. 传参
2. 执行函数体代码
3. 返回值
*/
let res = getSum(100,50);
console.log(res);
/*
函数总结
1.函数几种形态
无参无返回 : 使用较少
无参有返回 : 使用不多
有参无返回 : 使用不多
有参有返回 : 使用最多
2.函数完整的工作流程(原理)
a. 传参 : 调用者传递数据给函数
b. 执行函数体代码
c. 返回值 : 函数将结果返回给调用者
3.函数返回值语法注意点
a. 如果函数没有写return,默认返回值是undefined
b. 如果函数有写return,但是后面没有接值。返回值是undeifined
c. 如果函数有写return,并且return后面有值。返回值就是return后面的值
d. return关键字作用 : 结束函数体代码。 return后面代码不执行
*/
</script>
</body>
</html>
1.4-函数另一种声明方式
- 1.函数声明:function 函数名() {};
- 2.函数表达式:let 函数名 = 匿名函数
- 匿名函数:函数的字面量又称为匿名函数,顾名思义就是没有变量名的函数
- let 函数名 = function(){};
- 3.两者唯一区别:函数声明可以在任何地方调用,而函数表达式方式调用必须在声明后面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
fn1();
//1.函数声明 : function 函数名(){ 函数体代码 }
function fn1(){
console.log('11111');
};
fn1();
//2.表达式声明 : let 函数名 = 匿名函数
//具名函数 : 有名字的函数 匿名函数 = 没名字的函数
// fn2();//报错
let fn2 = function(){
console.log('2222');
};
fn2();
//3.唯一区别 : 函数声明可以在任何地方调用,表达式声明只能在声明后调用
</script>
</body>
</html>
1.5-函数练习
- 利用函数实现对应数组的最大值元素获取
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*函数三要素
1.功能
2.参数
3.返回值
*/
// 1.写一个函数:求任意数组的最大值
/**
* @description: 求任意数组最大值
* @param {array} arr : 数组
* @return: max:最大值
*/
function getMax(arr) { //let arr = [88,90,100,20,66]
//擂台思想
let max = -Infinity;
for (let i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
};
};
return max;
};
let max1 = getMax([88, 90, 100, 20, 66]);
console.log(max1);
//注意:函数是用来实现代码复用的,函数实现的功能越小,代码的复用性越强,所以不要尝试让一个函数去解决所有问题;而是多用几个函数去实现不同功能,然后大功能调用几个小函数实现
//如:数组获取最大值,获取最小值,获取平均值应该是三个不同的函数
</script>
</body>
</html>
1.6-函数实战思想
- 函数应该独立存在于js文件
- 在需要使用对应函数的html中引入js文件
/**
* arr.js
* @description: 求任意数组最大值
* @param {array} arr : 数组
* @return: max:最大值
*/
function getMax(arr) { //let arr = [88,90,100,20,66]
//擂台思想
let max = -Infinity;
for (let i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
};
};
return max;
};
//可以将数组相关操作的函数封装到一个文件中,形成自己的API库
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="js/arr.js"></script>
</head>
<body>
<script>
//直接调用引入的js文件中的函数即可
let max = getMax([88, 90, 100, 20, 66]);
console.log(max);
</script>
</body>
</html>
1.7-封装自己的API库
-
将自己所做的内容沉淀下来,供未来使用
-
懂得根据业务进行分类
-
今日作业要求:函数都需要定义这js文件中,使用外联方式引入js
-
1.实现柱状图(从上面生长)
function createBarChart() {
// 生成大盒子.box
document.write(`
<div class="box" style="width: 1200px;
height: 200px;
border:1px solid #000;
margin: 50px auto;
display: flex;
justify-content: space-evenly;
align-items: flex-start;">
`);
let num = prompt('请输入柱状图个数');
let width = 1200 / (2 * num - 1);
for (let i = 0; i < num; i++) {
let height = Math.floor(Math.random() * 200);
let red = Math.floor(Math.random() * 255);
let green = Math.floor(Math.random() * 255);
let blue = Math.floor(Math.random() * 255);
document.write(`
<div style="height: ${height}px;width: ${width}px;background-color: rgb(${red},${green},${blue});">
</div>
`);
}
document.write(`</div>`)
}
- 2.使用函数实现将数组中指定的元素去掉(★)
- function arrTrip(数组,要去除的变量)
- 例如:[0,10,20,30,0,40,0] 变成[10,20,30,40]:arrTrip([0,10,20,30,0,40,0] ,0)
function arrTrip(arr, index) {
// 定义一个空数组
let newArr = [];
// 对这个数组进行遍历
// 判断数组的每一个元素 是否等于要去除的那个数
// 如果不等于这个值 该元素加入新数组
for (let i = 0; i < arr.length; i++) {
if (arr[i] !== index) {
newArr[newArr.length] = arr[i];
}
}
return newArr;
}
- 3.使用函数求出数组中是否所有的数字都是正数,打印结果(★★)
- 例如:[10,20,30,40,50],打印:true
- 例如:[-10,20,30,40,50],打印:false
function isPositive(arr) {
// 对这个数组进行遍历
//判断这个数组里的每一个元素 是否小于0
//如果小于0 直接停止遍历 返回false
//如果大于0 继续遍历下一个元素
// 数组遍历完 全部大于0 的话 返回true
for (let i = 0; i < arr.length; i++) {
if (arr[i] < 0) {
return false;
}
}
return true;
}
- 4.使用函数求出任意指定数组中的最小值(★)
function getArrMin(arr) {
// 使用擂台思想 定义一个变量 假设它为最小值
// 对数组进行遍历 跟这个最小值进行比较
// 如果数组里有元素比他小 取代他成为最小值
let min = arr[0];
for (let i = 1, len = arr.length; i < len; i++) {
if (min > arr[i]) {
min = arr[i];
}
}
// 返回这个最小值
return min;
}
- 循环嵌套题目
- 5.大马驮2石粮食,中马驮1石粮食,两头小马驮一石粮食,要用100匹马,驮100石粮食,该如何调配?(★★★)
let count = 0;
for (let i = 0; i <= 100 / 2; i++) {
for (let j = 0; j <= 100 - 2 * i; j++) {
if ((100 - 2 * i - j) % 0.5 == 0) {
let k = (100 - 2 * i - j) / 0.5;
if (parseInt(k) == k && k <= 100 && i + j + k == 100) {
count++;
console.log(`${i}只大马,${j}只中马,${k}只小马`)
}
}
}
}
console.log(count);
</script>
- 6.小明单位发了100元的购物卡,小明到超市买三类洗化用品,洗发水(15元),香皂(2元),牙刷(5元)。要把100元整好花掉,可如有哪些购买结合?(★★★★)
<script>
// 6.小明单位发了100元的购物卡,小明到超市买三类洗化用品,洗发水(15元),香皂(2元),牙刷(5元)。要把100元整好花掉,可如有哪些购买结合?(★★★★)
let count = 0;
for (let i = 0; i < 100 / 15; i++) {
for (let j = 0; j < (100 - 15 * i) / 5; j++) {
if ((100 - 15 * i - 5 * j) % 5 == 0) {
let k = (100 - 15 * i - 2 * j) / 5;
if (parseInt(k) == k) {
count++;
console.log(`${i}个洗发水,${j}个香皂,${k}个牙刷`)
}
}
}
}
console.log(count);
</script>
-
(1) 1000~ 5000之间有多少整数,其各位数字之和为5,分别是哪些数(例如整数2003的各位数字之和为 2+0+0+3 ,等于5)),并统计满足条件的整数有多少个。(★★)
/*
定义一个count 用来计数
遍历1000-5000 之间的数
拿到 个十百千 四个位置的数
进行相加
等于5 count加一
*/
let count = 0;
for (let i = 1000; i <= 5000; i++) {
// 千位
let num1 = parseInt(i / 1000);
// 百位
let num2 = parseInt(i / 100) % 10;
// 十位
let num3 = parseInt(i / 10) % 10; //1213 => 121 %10 =>1
// 个位
let num4 = parseInt(i) % 10;
// 求和 判断和是否为5 是的话计数器加一 输出这个数;
let sum = num1 + num2 + num3 + num4;
if (sum == 5) {
document.write(${i},其各位数字之和为5<br>
);
count++;
}
}
// 循环结束 拿到计数器 输出计数器值
document.write(1000~ 5000之间有多少整数,一共有${count}个数,其各位数字之和为5
); -
(2)猜数字游戏. 随机产生1个1-100之间的数 让用户猜(★★)
- 当用户输入的数比产生的随机数大 就输出 猜大了 并让用户继续输入新的数.。 当用户输入的比产生的随机数小的时候 就输出 猜小了 并且继续猜 当用户刚好输入的就是这个随机数的时候 提示成功 并显示用户猜了多少次
- a. 先产生1-100的随机数 b. 写1个循环 让用户反复不停的去猜 直到猜对结束.
- 当用户输入的数比产生的随机数大 就输出 猜大了 并让用户继续输入新的数.。 当用户输入的比产生的随机数小的时候 就输出 猜小了 并且继续猜 当用户刚好输入的就是这个随机数的时候 提示成功 并显示用户猜了多少次
1.1-寻找水仙花数
/**
* 水仙花数:是一个三位数,每一位的数字的三次方相加刚好等于自身
* 例如: 153 = 111 + 555 + 333
* = 1 + 125 + 27
* = 153
*
* 如何知道一个三位数的百位十位个位的数字?
* 例如:235
* 百位(除以一百取整): (1)235/100 = 2.35 (2)parseInt(2.35) = 2;
* 十位(除以10求模):(1)235/10 = 23.5 (2)parseInt(23.5)%10 = 3;
* 个位(模10): 235%10 = 5;
*
*/
/*思路分析:(1)遍历所有的三位数 100-999
(2)将每一位的数字三次方后相加判断是否是水仙花数
(3)如果是则打印这个数,然后继续寻找
(3.1)如果不是,则不打印继续寻找
*/
for(let i = 100;i <= 999;i++){//(1)循环所有的三位数
//2.判断是否是是水仙花数
let bai = parseInt(i / 100); // i/100结果是小数,通过parseInt可以取整
let shi= parseInt(i / 10) % 10;
let ge = parseInt(i) % 10;
if(Math.pow(bai,3) + Math.pow(shi,3) + Math.pow(ge,3) == i){
//(3)如果是水仙花数则打印
console.log ( "找到一个水仙花数:" + i );
}
//3.1 继续寻找
}
1.2-农场繁殖
- 农场第一年有两头牛,每两头牛每一年可以生一头小牛,小牛只需要吃草一年即可生牛,请问该农场需要多少年可以有一千头牛
/**
* 农场第一年有两头牛,每两头牛每一年可以生一头小牛
* 小牛只需要吃草一年即可生牛,请问该农场需要多少年可以有一千头牛
* * 例如
* * 第一年:两头牛 1 + 1 = 2
* * 第二年: 三头牛 2 + 1 = 3(生一头)
* * 第三年 :四头牛 3 + 3/2 = 4(两头牛生小牛,另一头旁边观望学习经验)
* * 第四年: 六头牛 4 + 4/2 = 6(两对牛各生一头小牛)
* * 总结:每一年增加的小牛数是农场总牛数除以2的倍数(取整)
*/
//1.初始两头牛
let sum = 2;
//2.死循环(省略条件判断),不达到一千的产量誓不罢休
for(let i = 2;;i++){ //第二年开始生小牛,所以循环变量初始值是2
sum += parseInt(sum/2);
if(sum >= 1000){
console.log("第" + i + "年,牛的数量是" + sum);//第17年,牛的数量是1066
break; //完成任务,停止循环
}
}