函数
思考:如果想要获取多个不同数组中的最大值怎么办
答:函数
1.定义
函数 (function ),执行特定任务的代码块
函数可以把具有相同或相似逻辑的代码 “ 包裹 ” 起来,通过函数调用执行这些被 ‘’ 包裹 ‘’的代码逻辑,这样做有利于精简代码方便复用
2.函数的基本使用
2.1声明函数
函数名命名规范
-
和变量名基本一致
-
尽量使用小驼峰式命名法
-
前缀应该为动词
-
命名建议:常用动词规定
2.2调用函数
注意点
-
声明(定义)的函数必须调用才会真正被执行,使用()调用函数
-
函数一次声明可以多次调用,每一次函数调用函数体里面的代码会重新执行一次
-
我们曾经使用的alert(),parseInt ()这种名字后面跟小括号的本质都是函数的调用
代码如下:
<script>
// 1.声明函数
function sayHi() {
console.log("早上好");
console.log("下午好");
console.log("晚上好");
}
// 2.调用函数
sayHi();
sayHi();
sayHi();
</script>
2.3 函数封装 = 抽取
封装的函数不够灵活 无法复用 没有感受到 提高!!
<script>
// 1.声明函数,
function getSum1() {
let num1 = 1;
let num2 = 2;
console.log(num1 + num2);
}
// 2.调用函数
getSum1();
</script>
3.函数传参
函数传参可以提高函数的灵活性
3.1 有参数的函数声明
注意点 :参数列表
- 传入数据列表
- 声明这个函数需要传入几个数据
- 多个数据要用逗号隔开
3.2 有参数的函数调用
调用函数时,需要传入几个数据就写几个,用逗号隔开
3.3 形参和实参
- 形参: 声明函数时写在函数名右边()里面的就叫形参(形式上的参数)
- 声明定义的时候,形参只是参数占位
- 在调用方法(用的时候肯定有括号的就讲方法)的时候,形参是一个变量
- 相当于在方法中声明的局部变量,只有在方法内部可以使用,在方法外部使用,会报错
- 实参: 调用函数时写在函数名右边()里面的就叫实参(实际上的参数)
- 调用的时候,尽量让形参和实参顺序对应,数量对应,类型对应
小试牛刀案例1
需求:学生的分数是一个数组,计算每个学生的总分
代码如下
<script>
/* 需求:学生的分数是一个数组,计算每个学生的总分 */
// 假设a同学的分数数组
let arr1 = [10, 2, 30, 4, 50];
// 假设b同学的分数数组
let arr2 = [1, 20, 3, 40, 5];
// 声明函数
function getSum1(a) {
// 声明一个变量总和sum
let sum1 = 0;
for (let index = 0; index < a.length; index++) {
sum1 += a[index];
}
console.log(sum1);
}
// 调用函数
getSum1(arr1);
getSum1(arr2);
</script>
小试牛刀案例2
需求:写一个函数,接收一个参数-数组,输出最大值、
代码如下
<script>
// 需求:写一个函数,接收一个参数-数组,输出最大值、
// 2.第二步声明一个有参数的函数
function getMax(a) {
// 1.先完成数组输出最大值
// let arr = [1, 3, 5, 7, 11];
// 假设最大值的数组就等于旧数组中第0个元素
let maxArr = a[0];
for (let index = 0; index < a.length; index++) {
if (a[index] > maxArr) {
maxArr = a[index];
}
}
console.log(maxArr);
}
// 3.第三步调用有参数的函数
getMax([1, 3, 5, 7, 11]);
</script>
小试牛刀案例3
需求:写一个函数,接收一个参数数组 ,计算数组中的奇数的和
代码如下
<script>
// 创建数组
let arr1 = [1, 3, 5, 20, 40, 7];
// 声明函数
function getSum(a) {
// 创建总和一开始为0 奇数总和 sum
let sum = 0;
for (let index = 0; index < arr1.length; index++) {
// 奇数=当前数组元素 % 2 !== 0
if (arr1[index] % 2 !== 0) {
// 奇数和
sum += arr1[index];
}
}
console.log(sum);
}
// 调用函数
getSum(arr1)
</script>
4.函数返回值
定义 :函数执行后得到结果,结果是调用者想要拿到的(一句话,函数内部不需要输出结果,而是返回结果)
好处执行结果的扩展性更高,可以让其他的程序使用这个结果
return关键字可以实现返回值
注意点
- return 变量
- 一个函数只能返回一个变量,如果有多个值需要返回,可以将多个值包装到数组,返回这一个数组
- return:可以中止函数,函数中运行到return后面的代码都不再执行,所以return如果想要返回结果,后面的数据不要换行写
- 一个函数中只有一个return可以被执行
- 调用的函数如果有返回值,可以定义一个变量用于接收这个函数的返回值
- 函数返回了什么值,你就可以接收到什么值
- 如果函数没有返回值,默认会返回undefined
小试牛刀案例1
需求. 求任意数组中的最大值并返回这个最大值
代码如下
<script>
/* 需求. 求任意数组中的最大值并返回这个最大值
*/
// 声明有参数的函数 ,a传参等于[1, 11, 2, 3, 44, 55, 6]
function getMax(a) {
let max = a[0];
// 数组循环
for (let index = 0; index < a.length; index++) {
if (a[index] > max) {
max = a[index];
}
}
// 返回最大值
return max;
}
// 调用有参数的函数
// getMax([1, 11, 2, 3, 44, 55, 6]);
// 函数max调用的返回值
let max = getMax([1, 11, 2, 3, 44, 55, 6]);
console.log(max);
</script>
5.作用域
5.1定义
一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突
5.2 三种作用域
全局作用域:在script标签中声明的成员
函数作用域:局部作用域:在函数内部声明的成员
块级作用域:在{}中声明的成员
<script>
// script标签内的运行环境就是全局作用域
let num = 100; // 全局作用域
function getMax() {
// 这个区域内就不属于全局作用域
// 局部作用域 或者 也叫做 函数作用域
let num2 = 200;
}
for (let index = 0; index < 4; index++) {
// 块级作用域
}
while (true) {
// 块级作用域
}
if (true) {
// 块级作用域
}
</script>
5.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);// 使用块级变量 出错!!
</script>
注意点
- 有一种特殊情况是全局变量是局部变量或者块级变量 没有let 声明直接赋值的当全局变量看,我们强烈不提倡
- 还有一种特殊情况,函数内部的形参可以当做局部变量看
5.4 作用域链
只是代码寻找变量的一种机制,规定就近原则,判断是要根据函数的定义来判断,而不是函数的调用
-
首先先找自己的作用域num (没找到)
-
往外部(父级)的作用域来找(没找到)
-
继续往外部(父级)来找
-
直到找到全局作用域 停止下来了
6.匿名函数
函数按照有没有名字 分成两种
-
具名函数 有具体名字的
// 具名函数 函数名称 func1 function func1() { } -
匿名函数 没有名字 function () {}
function () { // 设置 页面的标题 = 月薪过万 document.title = '月薪过万'; // 设置 页面的背景颜色 = 黄色 document.body.style.backgroundColor = 'yellow'; }函数的表达式就是可以表示结果的一段代码
写法如下: let fn = function(){}
自执行函数:匿名函数一起出现 通用的功能是 防止变量污染
(function () {
let msg = 123;
// 设置 页面的标题 = 月薪过万
// document.title = '月薪过万';
// 设置 页面的背景颜色 = 黄色
document.body.style.backgroundColor = 'yellow';
})();