JavaScript
函数
一、什么是函数,为什么需要函数?
1.function,是被设计为执行特定任务的代码块
2.函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于精简代码方便复用。(可以实现代码复用,提高开发效率)
3、体验函数魅力(案例---筛选多个数组的最大值)
<script>
let arr1 = [1, 3, 2, 66, 33, 22];
let arr2 = [1, 3, 2, 663, 33, 22];
let arr3 = [1, 3, 2, 665, 33, 22];
let max1 = getMax(arr1);
let max2 = getMax(arr2);
let max3 = getMax(arr3);
console.log(max1, max2, max3);
function getMax(arr) {
let max = arr[0];
for (let index = 0; index < arr.length; index++) {
if (arr[index] > max) {
max = arr[index];
}
}
return max;
}
</script>
二、函数使用
1.目标:掌握函数语法,把代码封装起来
2.语法
function 函数名() {
函数体
}
function sayHi() {
document.write(`sayhi`)
}
3.函数名命名规范
①和变量命名基本一致 ②尽量小驼峰式命名法 ③前缀应该为动词 ④命名建议:常用动词约定
4.函数调用语法
//函数调用,这些函数体内的代码逻辑会被执行
函数名()
//函数一次声明可以多次调用,每一次函数调用函数体里面的代码会重新执行一次
sayhi()
sayhi()
//alert()、parseInt()也属于函数调用
<script>
//函数声明
function sayHi() {
console.log("你好");
console.log("你真好");
console.log("你真tm的好");
//调用函数
sayHi();
sayHi();
sayHi();
}
</script>
5.函数体
函数体是函数的构成部分,它负责将相同或相似代码“包裹”起来,直到函数调用时函数体内的代码才会被执行。函数的功能代码都要写在函数体当中。
function sayHi() {
console.log(`嗨`);
}
sayHi()
6.案例-九九乘法表
<script>
// 1 声明函数 - 输出 99乘法表
function calcNum() {
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/>");
}
}
// 2 调用函数
calcNum();
calcNum();
calcNum();
</script>
7.封装
①目的:通过这段代码 封装 成函数,体会函数的好处
如:CSS里面,通过取类名将相同属性的属性及属性值写在一起
②特点:封装的函数不够灵活 无法复用 没有感受到 提高
// 只能计算 100 + 1
function calcSum1() {
let a = 100;
let b = 1;
console.log(a + b);
}
// 计算 3 + 2 的和
function calcSum3() {
let a = 3;
let b = 2;
console.log(a + b);
}
// 只能计算 1-100 和
function calcSum2() {
let sum = 0;
for (let index = 1; index <= 100; index++) {
sum += index;
}
console.log(sum);
}
// 计算 1-50 的和
function calcSum3() {
let sum = 0;
for (let index = 1; index <= 50; index++) {
sum += index;
}
console.log(sum);
}
calcSum1();
calcSum2();
calcSum3();
// console.log();
// d
ocument.write()
// alert(789);
三、函数传参
1.为什么需要传参函数?
①若函数完成功能需要调用者传入数据,那么就需要用有参数的函数
②提高函数的灵活性
2.语法
function 函数名(参数列表) {
函数体
}
//单个参数
function getSquare(num1) {
document.write(num1*num1)
}
//多个参数
function getSquare(num1,num2) {
document.write(num1+num2)
}
<script>
// 声明函数
function getSum(num1, num2) {
// num1 = 100
// num2 = undefined
console.log(num2);
document.write(num1 + num2);
// 100 + undefined
}
// function getSum(a, b) {
// document.write(a + b);
// }
// getSum(10, 20);
// getSum(100, 200);
</script>
3.形参和实参(开发中尽量保持形参和实参个数一致)
①形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
②实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)
③参数中间用“逗号”隔开
function getSum(num1, num2) {
console.log(num2);
document.write(num1 + num2);
}
getSum(10, 20);
getSum(100, 200);
4.传参封装求和
需求:采取函数封装的形式:输入2个数,计算两者的和,打印到页面中
function getSum(x,y) {
x=x || 0
y=y || 0
console.log(x+y)
}
getSum(1,2)
// 数组求和
<script>
function getSum(arr) {
let sum = 0;
for (let index = 0; index < arr.length; index++) {
sum += arr[index];
}
console.log(`总分:${sum}`);
}
let arr1 = [2, 5, 7, 8, 14, 26];
let arr2 = [3, 5, 9, 17, 14, 26];
getSum(arr1);
getSum(arr2);
</script>
四、函数返回值return
1.为什么要让函数有返回值?
因为函数被设计为执行特定任务的代码块,把计算后的结果处理方式写死了,内部处理了。把处理结果返回给调用者,当调用某个函数,这个函数会返回一个结果出来。
2.用return返回数据
①语法
return 数据
function getSum(x,y) {
return x+y
}
let num = getSum(10,30)
document.write(num)
3.return细节
①在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用 ②函数内部只能运行到 1 次 return,并且 return 后面代码不会再被执行,所以 return 后面的数据不要换行写 ③return会立即结束当前函数 ④函数可以没有 return,这种情况函数默认返回值为 undefined
4.案例(一)
<script>
// 函数 参数的最大值
function getMax(n1, n2) {
if (n1 > n2) {
return n1;
} else {
return n2;
}
}
// 通过 console.log 帮我打印
// let num1 = getMax(1, 3);
// console.log(num1);
// let num1 = getMax(1, 3);
console.log(getMax(1, 3));
// 通过 document.write 帮我打印
// let num2 = getMax(2, 4);
document.write(getMax(2, 4));
// 通过 alert 帮我打印
// let num3 = getMax(6, 8);
alert(getMax(6, 8));
</script>
案例(二)
<script>
let arr1 = [1, 3, 4, 33, 22];
// 声明一个函数 用来计算数组最大值 且最大值 返回
function getMax(arr) {
let max = arr[0];
for (let i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
let max = getMax(arr1);
console.log(max);
// 声明一个函数 用来计算数组最小值 且最小值 返回
function getMin(arr) {
let min = arr[0];
for (let i = 0; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
return min;
}
let min = getMin(arr1);
console.log(min);
</script>
5.return补充
<script>
/*
1 不能同时执行多次return 第一个return生效
2 函数内部 如果写了return ,那么它下面的代码就不会执行!!
3 如果一个函数 没有写return 相当于 写了 return undefined
*/
function getMax() {
return undefined;
}
let num = getMax();
console.log(num);
</script>
五、作用域
1.作用域概述:通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
2.作用域分为:全局作用域、局部作用域、块级作用域
//全局作用域
整个 script 标签内部或者一个独立的 js 文件
//局部作用域
作用于函数内的代码环境,也叫函数作用域
//块级作用域
块作用域由 { } 包括,if语句和for语句里面的{ }等
3.变量作用域分为:全局变量、局部变量、块级变量
//全局变量
全局变量在变量定义之后区域可以访问和修改
//局部变量
局部变量只能在当前函数内部访问和修改
//块级变量
let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问
4.案例-变量作用域
①全局变量
<script>
// 直接写在全局作用域下的变量 = 全局变量 在任意的地方来访问
let num = 100; // 全局变量 在任何地方都可以访问
function getMax() {
console.log("函数 访问全局变量", num);
}
getMax();
for (let index = 0; index < 2; index++) {
console.log("for循环内 块级作用域 访问全局变量", num);
}
if (true) {
console.log("if语句 也 可以访问全局变量", num);
}
</script>
②局部变量
<script>
// 局部变量
// 如果是在函数内部定义的变量 就叫做局部变量
// 局部变量 不能在 它的大括号之外使用的,否则就会报错!!
let msg = 10000; // 全局变量
// 局部变量 函数内部 声明的变量
function getMax() {
// 声明一个数字
let num = 200; // 局部变量
}
// 局部变量 不能在 超出它的大括号来使用
console.log(num); // 会报错
</script>
③块级变量
<script>
// 块级变量 就是我们在块级作用域内 定义的变量
// 块级变量 类似局部变量,也是超出了自身的大括号 不能使用
// for (let index = 0; index < 2; index++) {
// // num 块级变量
// let num = 100;
// }
// console.log(num);// 使用块级变量 出错!!
// {
// let num =10;
// }
// {
// console.log(num);
// }
/*
小结
1 分类 分成两类即可
1 全局变量
直接放在 script标签内的变量
2 局部变量 用大括号包起来的变量
1 函数内部变量
2 块级变量
*/
</script>
5.变量访问原则---作用域链
采取就近原则的方式来查找变量最终的值
6.变量的使用
<script>
// 在同一个作用域内 声明两个同样变量 就会出错。
// 全局变量
// let num = 100;
// let num = 200;
// function getMax() {
// let num = 100;
// }
// function getMin() {
// let num = 200;
// }
// for (let index = 0; index < 2; index++) {
// let num = 100;
// console.log("第一次循环,",num);
// }
// for (let index = 0; index < 2; index++) {
// let num = 100;
// console.log("第二次循环,",num);
// }
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;
}
function sdfdf(params) {}
</script>
<script>
let num = 100;
function getMax() {
// let num =200;
console.log(num); // 200 就近原则 寻找变量的时候 优先找自己的作用域
}
getMax();
</script>
<script>
let num = 100;
function getMax() {
let num = 200;
for (let index = 0; index < 1; index++) {
let num = 300;
console.log(num);
}
}
getMax();
</script>
7.函数的嵌套使用
<script>
function func1() {
console.log("func1");
func2();
}
function func2() {
console.log("func2");
func3();
}
function func3() {
console.log("func3");
}
func1(); // 输出什么 1
</script>
8.作用域链测试
①测试一
<script>
// let num = 100;
// function func1() {
// let num = 200;
// fun2();
// }
// function fun2() {
// let num = 300;
// console.log(num); // 300
// }
// func1();
// 判断当前变量 输出是什么
// 就近原则 判断是要根据 函数的定义 来判断 而不是函数的调用
// 函数的定义 代码位置来判断 100 这个!!
let num = 100;
function func1() {
let num = 200;
// 函数的调用
fun2();
}
// 函数的定义-声明
function fun2() {
console.log(num);
}
func1();
</script>
②测试二
<script>
// 从函数的定义出发 依据 就近原则 来寻找变量即可
let num = 100;
function func1() {
let num = 200;
function fun2() {
console.log(num);
}
fun2();
}
func1(); // 输出什么
</script>
六、匿名函数
1.语法
①具名函数
//声明 function fn() {}
调用 fu()
②匿名函数
function() {}
let fn=function() {}
2.匿名函数使用场景:避免全局变量之间污染
方式一:(function () { console.log(11) })();
方式二:(function () { console.log(11) })();
// 不需要 调用 立刻执行
<script>
// 函数按照有没有名字 分成两种
// 有名字 具名函数
// 没有名字 匿名函数
// 具名函数 函数名称 func1
// function func1() {
// }
// 匿名函数 = function () {}; 匿名函数 了解即可
// let func2 = function () {}; 叫做 函数表达式
// 表达式 可以表示结果的一段代码 函数表达式 了解
let func2 = function () {
console.log("123");
};
// 调用
func2();
</script>
七、自执行函数
<script>
/*
自执行函数 = 匿名函数一起出现 通用的功能是 防止变量污染
函数在定义的同时 直接就执行了
用在哪里呢
适合做一次性的任务- 不希望这个函数可以得到复用!!!
函数包装多段代码 让程序比较简洁
1 页面打开时候
1 设置 页面的标题 = 月薪过万
2 设置 页面的背景颜色 = 黄色
*/
// 匿名函数
// function () {
// // 设置 页面的标题 = 月薪过万
// document.title = '月薪过万';
// // 设置 页面的背景颜色 = 黄色
// document.body.style.backgroundColor = 'yellow';
// }
// let msg = 123;
// // 自执行函数
// (function () {
// let msg = 123;
// // 设置 页面的标题 = 月薪过万
// document.title = '月薪过万';
// // 设置 页面的背景颜色 = 黄色
// document.body.style.backgroundColor = 'yellow';
// })();
// console.log(msg);
</script>