day6
函数
函数: function,是被设计为执行特定任务的代码块。
作用: 函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于精简代码方便复用。
函数的声明语法
<script>
function 函数名(){
函数体
}
</script>
函数名命名规范:
- 和变量命名基本一致 ;
- 尽量小驼峰式命名法 ;
- 前缀应该为动词 ;
- 命名建议:常用动词约定 .
动词 :
| 动词 | 含义 |
|---|---|
| can | 判断是否可执行某个动作 |
| has | 判断是否含义某个值 |
| is | 判断是否为某个值 |
| get | 获取某个值 |
| set | 设置某个值 |
| load | 加载某些数据 |
函数体
函数体是函数的构成部分,它负责将相同或相似代码“包裹”起来,直到函数调用时函数体内的代码才会被执行。函数的功能代码都要写在函数体当中。
函数的调用语法
-
声明(定义)的函数必须调用才会真正被执行,使用 () 调用函数 .
-
我们曾经使用的 alert() , parseInt() 这种名字后面跟小括号的本质都是函数的调用
<script>
函数名();
函数名();
</script>
示例:
<script>
//函数的声明
function sayhi() {
console.log('你好啊');
console.log('你们好');
console.log('大家好');
}
//函数调用 ,写了3个,上面的代码重复了3遍
sayhi();
sayhi();
sayhi();
</script>
函数的复用代码和循环重复代码有什么不同? 循环代码写完即执行,不能很方便控制执行位置 ; 随时调用,随时执行,可重复调用。
函数调用案例
99乘法表-函数调用 :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>99乘法表-函数调用</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
span {
border: 1px solid #000;
padding: 10px 0;
width: 100px;
text-align: center;
display: inline-block;
}
</style>
</head>
<body>
<script>
//声明函数, 把表格整个放进去
function getTable() {
for (let index = 1; index <= 9; index++) {
for (let index1 = 1; index1 <= index; index1++) {
let num = index1 * index;
document.write(`<span> ${index1} * ${index} = ${num} </span>`);
}
document.write('<br/>');
}
}
//调用3次
getTable();
getTable();
getTable();
</script>
</body>
</html>
函数的嵌套
以上示例 嵌套,打印显示:
func1
func2
func3
函数传参
使用语法:
<script>
//声明语法
function 函数名参数列表{
函数体
}
//调用语法
函数名(传递的参数列表)
</script>
参数列表 :
- 传入数据列表;
- 声明这个函数需要传入几个数据;
- 多个数据用逗号隔开。
实参和形参 :
- 形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)。
- 实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)。
- 形参可以理解为是在这个函数内声明的变量(比如 num1 = 10)实参可以理解为是给这个变量赋值。
- 开发中尽量保持形参和实参个数一致。
- 我们曾经使用过的 alert('打印'), parseInt('11'), Number('11') 本质上都是函数调用的传参。
示例:
<script>
//声明语法
function getSum(num1,num2){
document.write(num1 + num2)
}
//调用语法 里面对应是100对应上面的num1 ,200对应num2, 打印出来结果显示是300
getSum(100, 200)
</script>
课堂案例
计算总分
<script>
//函数声明
function calcSum(arr) {
let sum = 0; //声明 总和
for (let index = 0; index < arr.length; index++) {
sum += arr[index];
}
console.log(sum);
}
//函数调用
let arr1 = [1, 3, 4, 2, 22];
let arr2 = [3, 2, 3, 3, 55];
calcSum(arr1);
calcSum(arr2);
</script>
计算奇数和
<script>
let arr = [1, 3, 4, 1, 22, 3, 4, 5]
function getSum(arr) {
let sum = 0;
for (let index = 0; index < arr.length; index++) {
if (arr[index] % 2 !== 0) {
sum += arr[index];
}
console.log(sum)
}
}
getSum(arr);
</script>
计算最大值
<script>
let a = [1, 3, 2, 2, 4, 5]
function getMax(a) {
let max = a[0];
for (let index = 0; index <= a.length; index++) {
if (a[index] > max) {
max = a[index];
}
}
console.log(max)
}
let max = getMax(a)
</script>
函数返回值
return 返回值的使用
- 不能同时执行多次return,只有第一个return生效。
- 函数内部 如果写了return,那么它下面的代码就不会执行!!
- 如果一个函数 。没有写return 相当于写了 return undefined。
函数返回值 案例
<script>
//return 返回值的使用
//求函数最大值
function getMax(n1,n2){
if(n1 > n2){
return n1; //不写死那种输出方式,写返回值
} else{
return n2
}
}
//通过console.log 打印出来最大值
console.log(getMax(1,3));
//通过document.write 打印最大值
document.write(getMax(2,4))
//通过alert 打印最大值
alert(getMax(6,8))
</script>
求最大值
<script>
let arr1 = [1,3,4,33,22];
//声明一个函数 用来计算数组的最大值
function getMax(arr){
let max = arr[0];
for (let index = 0; index < arr.length; index++){
if(arr[index] > max){
max = arr[index];
}
}
return max;
}
let max = getMax(arr1);
console.log(max);// 显示最大值
</script>
求最小值
<script>
let arr1 = [1,3,4,33,22];
//声明一个函数 用来计算数组的最小值
function getMax(arr){
let min = arr[0];
for (let index = 0; index < arr.length; index++){
if(arr[index] < min){
min = arr[index];
}
}
return min;
}
let min = getMax(arr1);
console.log(min);// 显示最大值
</script>
作用域
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
全局作用域
作用于所有代码执行的环境(整个 script 标签内部)或者一个独立的 js 文件。
- 全局变量 在任何地方都可以访问。
局部作用域
作用于函数内的代码环境,就是局部作用域。 因为跟函数有关系,所以也称为函数作用域。
- 如果是在函数内部定义的变量,就叫局部变量。
- 局部变量 不能在 他的大括号之外使用的,否则会报错。
块级作用域
块作用域由 { } 包括,if语句和for语句里面的{ }等。
- 块级变量 就是我们在块级作用域内定义的变量。
- 块级变量 类似局部变量, 也是超过自身的大括号,不能使用。
- 块级作用域和函数变量 规则差不多,通常分类就按全局变量和局部变量。
<script>
//script标签内的运行环境就是全局作用域
let num = 100; //全局作用域
function getMax() {
//整个区域就不属于全局作用域
//叫做 局部作用域 或者 函数作用域
}
for (let index = 0; index < array.length; index++) {
//块级作用域
}
while ( ) {
//块级作用域
}
if ( ) {
//块级作用域
}
</script>
变量的使用补充
- 同一个作用域内 声明两个一样的变量 会出错。
- 在不同个局部区域 分别定义变量,名字一样的也不会出错。
- 如果全局区域 和 局部区域 有同样的变量,打印结果是就近原则,优先寻找自己的作用域,如自己的作用域没有就往外找。
- 作用域链 只是 代码 寻找变量的一种机制,规定,就近原则。
- 就近原则 ,判断是要根据 函数的定义(声明)的 位置来判断, 而不是根据函数的 调用位置 判断。
- 定义一个变量 没有使用 let 关键字, 那么他就是一个全局变量。
匿名函数
- 函数按照有没有名字 分成两种
- 有名字的 具名函数
- 没有名字 匿名函数
function (){
//函数体
}
自执行函数
适合做一次性的任何, 不希望整个数再被复用。
自执行函数 是和 匿名函数一起出现的。
作用: 防止变量污染。里面的变量和外面一样,互不冲突。
写法:
()()
- 第一个括号放匿名函数的内容进去就行
自动转换时分秒案例
<script>
// 声明一个函数 做到 输入了 秒 返回 时:分:秒
// PPT 希望 把 时分秒 返回 返回一个数组 [时,分,秒]
function getTime(time) {
// 总秒数 是这个 time
// 来计算 小时 parseInt 取整数,小时 = 总秒数 / 60 / 60 % 24 (时间太长可能会超过24小数,所以取余24,超过24小时的不要)
let hour = parseInt(time / 60 / 60 % 24);
// 思路 先将秒转成总的分钟数 parseInt 取整数,分钟 = 总秒数 / 60 % 60(可能会超过60分钟,对60 取余 )
let minute = parseInt(time / 60) % 60;
// 秒 直接对60 取余即可
let second = time % 60;
// 补0 处理
hour = hour < 10 ? '0' + hour : hour;
minute = minute < 10 ? '0' + minute : minute;
second = second < 10 ? '0' + second : second;
// console.log(hour, minute, second);
// 返回了一个数组
return [hour, minute, second];
}
// return 可以返回多个值吗 ??
// 最严谨的说法 不可以的
// 较真 可以
// function getNum() {
// // return 1
// // return 2
// // return 3
// // 返回一个数组
// return [1, 2, 3, 4];
// }
// 用户输入一个 秒数 返回 时分秒 数组
let times = getTime(+prompt("请输入总秒数");
console.log(times);
// 写在网页上
document.write(`${times[0]}:${times[1]}:${times[2]}`);
</script>