Javascript基础day06
JS - 函数
函数
• 为什么需要函数
函数:
- function,是被设计为执行特定任务的代码块
说明:
- 函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于精简代码方便复用。
函数的声明语法
!
函数的调用语法
体验函数场景
<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>
• 函数使用
通过这段代码 封装 成函数,体会函数的好处
<script>
// 1 函数的声明
function sayHi() {
console.log('你好');
console.log('你真好');
console.log('你真TM好');
}
// 2 函数调用
// sayHi();
// sayHi();
// sayHi();
</script>
函数封装
<script>
// 封装的函数不够灵活 无法复用 没有感受到 提高!!
// 计算 3 + 2 的和
// 计算 1-50 的和
// 只能计算 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();
// console.log();
// document.write()
// alert(789);
</script>
<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>
• 函数传参
1. 为什么要有参数的函数
2.有参数有函数声明和调用
3. 形参和实参
- 形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
- 实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)
- 形参可以理解为是在这个函数内声明的变量(比如 num1 = 10)实参可以理解为是给这个变量赋值
- 开发中尽量保持形参和实参个数一致
- 我们曾经使用过的 alert('打印'), parseInt('11'), Number('11') 本质上都是函数调用的传参
<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>
• 函数返回值
1.为什么要让函数有返回值
使用场景
<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>
2.用return返回数据
细节:
- 在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用
- 函数内部只能出现 1 次 return,并且 return 后面代码不会再被执行,所以 return 后面的数据不要换行写
- return会立即结束当前函数
- 函数可以没有 return,这种情况函数默认返回值为 undefined
<script>
// function getMax() {}
// function getSum() {}
// // 这个num1 就是 函数getMax调用的返回值 ( num1 = 1 2 。。)
// // let num2 = getSum();
// let num1 = getMax();// 我们自己写的函数 只能返回 undefined
// let num3 = parseInt(1.3);// js自己内部写的 返回值 1
// console.log(num3); //
function getMax() {
// 100 就是 函数在执行完毕的时候 会返回的数据
return 300;
}
let num1 = getMax(); // num1 =100
console.log(num1);
</script>
使用场景
<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>
• 作用域
1.作用域概述
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
<script>
// script标签内的运行环境就是全局作用域
let num = 100; // 全局作用域
function getMax() {
// 这个区域内就不属于全局作用域
// 局部作用域 或者 也叫做 函数作用域
let num2 = 200;
}
for (let index = 0; index < 4; index++) {
// 块级作用域
}
while (true) {
// 块级作用域
}
if (true) {
// 块级作用域
}
</script>
2.变量的作用域
在JavaScript中,根据作用域的不同,变量可以分为
<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>
3.变量的作用域
变量有一个坑, 特殊情况: 如果函数内部或者块级作用域内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐 但是有一种情况,函数内部的形参可以看做是局部变量。
<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>
4.变量访问原则-作用域链
- 只要是代码,就至少有一个作用域
- 写在函数内部的局部作用域
- 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
- 根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链
案例
<script>
// 从函数的定义出发 依据 就近原则 来寻找变量即可
let num = 100;
function func1() {
let num = 200;
function fun2() {
console.log(num);
}
fun2();
}
func1(); // 输出什么
</script>
<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>
• 匿名函数
1.匿名函数
将匿名函数赋值给一个变量,并且通过变量名称进行调用 我们将这个称为函数表达式
<script>
// 函数按照有没有名字 分成两种
// 有名字 具名函数
// 没有名字 匿名函数
// 具名函数 函数名称 func1
// function func1() {
// }
// 匿名函数 = function () {}; 匿名函数 了解即可
// let func2 = function () {}; 叫做 函数表达式
// 表达式 可以表示结果的一段代码 函数表达式 了解
let func2 = function () {
console.log("123");
};
// 调用
func2();
</script>
使用场景
2. 立即执行函数
场景介绍: 避免全局变量之间的污染
<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>