JavaScript函数底子(平凡易懂篇)

[复制链接]
发表于 2026-1-13 06:01:15 | 显示全部楼层 |阅读模式
10.函数

10.1 函数的底子知识

为什么会有函数?
在写代码的时间,有一些常用的代码须要誊写许多次,如果直接复制粘贴的话,会造成大量的代码冗余;
函数可以封装一段重复的javascript代码,它只须要声明一次,就可以多次调用;
冗余代码:

  •         冗余:多余的重复或啰嗦内容
  •         缺点:

    •                 代码重复,可阅读性差
    •                 不易维护,如果代码逻辑变了,全部地方的代码都要跟着改,服从太低了

函数使用分为两步:声明函数 和 调用函数
10.2函数的使用

10.2.1 声明函数
函数声明的语法:
var 是用来声明变量的, 函数是用function来声明的,一个函数一样寻常是用来做一件事变的。
  1. function 函数名 (){
  2.    //函数体
  3. }
复制代码
  1. //例如:
  2. function sayHi(){
  3.    console.log("Hi~~")
  4. }
复制代码
注意:

  •         function 声明函数的关键字,必须小写
  •         函数是做某件事变,函数名一样寻常是动词,如:sayHi
  •         函数不调用自己不实验
           
10.2.2 调用函数
调用函数的语法:
  1. 函数名();
复制代码
函数体只有在调用的时间才会实验,调用须要()举行调用。可以调用多次
示例代码:
  1. // 声明函数
  2. function sayHi (){
  3.    // 函数体
  4.    console.log("Hi!!");
  5. }
  6. // 调用这个函数
  7. sayHi();  // console.log("Hi!!");
  8. // 注意
  9. console.log(sayHi);  // 打印的是整个函数
  10. // sayHi:指的就是这个函数
  11. // ():指的是调用
  12. // sayHi():这个函数的调用结果
复制代码
注意:

  •         调用函数的时间千万不要忘记加小括号
  •         函数不调用自己不实验

10.2.3 声明函数的两种方式
1、函数声明(定名函数):
  1. // 声明一个函数而且定名了function 函数名(){    函数体;}
  2. 函数名();  // 调用函数​/********示例代码***********/function fn(){    console.log("啊哈哈");}fn();
复制代码
2、函数表达式(匿名函数):
  1. // 必须先声明才气调用var 函数名 = function(){    函数体;}
  2. 函数名(); // 调用函数​/********示例代码***********/var fn = function(){    console.log("啊哈哈");}fn();
复制代码
这两种函数的区别:

  •         定名函数可以先调用,再声明,由于预剖析
  •         函数表达式必须先声明,再调用(在DOM中注册变乱的时间用的非常的多)
匿名函数:
没著名字的函数,叫做匿名函数。匿名函数没有办法直接用,须要赋值给变量大概自调用
自调用函数也叫自实验函数,声明和调用一起

  •         可以防止变量全局污染
  •         匿名函数自调用示例代码:
  1. (function(num1,num2){
  2.    console.log(num1);        // 1
  3.    console.log(num2);        // 2
  4.    var name = "张三"
  5.    var age = 18;
  6.    function sayHello() {
  7.      console.log(age);     // 18
  8.      console.log(name);    // "张三"
  9.    }
  10.    sayHello();
  11. })(1,2)
复制代码
10.3 函数的封装


  •         函数的封装是把一个大概多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口
  •         简单明白:封装雷同于将电脑配件整合组装到机箱中(雷同快递打包)
正在上传…重新上传取消

10.4 函数的参数

形参和实参
在声明函数时,可以在函数名称背面的小括号中添加一些参数,这些参数被称为形参,而在调用该函数时,同样也须要通报相应的参数,这些参数被称为实参
情势参数: 在声明一个函数的时间,为了函数的功能更加机动,有些值是固定不了的,对于这些固定不了的值。我们可以给函数设置参数。这个参数没有具体的值,仅仅起到一个占位置的作用,我们通常称之为情势参数,也叫形参。
实际参数: 如果函数在声明时,设置了行参,那么在函数调用的时间就须要传入对应的参数,我们把传入的参数叫做实际参数,也叫实参。
参数阐明形参情势上的参数函数,界说的时间通报的参数当时并不知道是什么实参实际上的参数,函数调用的时间通报的参数实参是通报给形参的参数的作用:在函数内部某些值不能固定,我们可以通过参数在调用函数时通报差别的值进去。
语法:
  1. //带参数的函数声明
  2. function 函数名(形参1, 形参2, 形参...){
  3.  //函数体
  4. }
  5. //带参数的函数调用
  6. 函数名(实参1, 实参2, 实参3);
复制代码
  1. // 1.函数可以重复相同的代码
  2.     function cook() {
  3.         console.log('酸辣土豆丝');
  4.     }
  5.     cook();
  6.     cook();
  7. // 2.我们可以利用函数的参数实现函数重复不同的代码
  8.     function 函数名(形参1,形参2...){           //在声明函数的小括号里面是形参(形式上的参数)
  9.     }
  10.     函数名(实参1,实参2...);                    //在函数调用的小括号里面是实参(实际的参数)
  11. // 3.形参和实参的执行过程
  12.     function cook(aru) {                    //形参是接受实参的aru =‘酸辣土豆丝·形参类似于一个变量
  13.         console.log(aru);
  14.     }
  15.     cook('酸辣土豆丝');
  16.     cook('大肘子');
  17. //4.函数的参数可以有,也可以没有个数不限
复制代码
案例:
  1. // 1.利用函数求任意两个数的和
  2.     function getSum(num1,num2) {
  3.         console.log(num1 + num2);
  4.     }
  5.     getSum(1,3);                //结果:4
  6.     getSum(3,8);                // 11
  7. // 2.利用函数求任意两个数之间的和
  8.     function getsums(start, end) {
  9.         var sum = e;
  10.         for ( var i = start; i <= end; i++)(
  11.             sum += i;
  12.         }
  13.     console.log(sum);
  14.     }
  15.     getSums(1,100);             // 5050
  16.     getsums(1,10);              // 55
  17. // 3.注意点
  18. //(1)多个参数之间用逗号隔开
  19. //(2)形参可以看做是不用声明的变量
复制代码
10.4.1函数形参实参个数不匹配题目:
参数个数阐明实参个 = 形参个数输出精确结果实参个数 > 形参个数只取到形参的个数(多余参数不实验)实参个数 < 形参个数多的形参界说为undefined,结果为NaN特点:

  •         在函数调用的时间,须要通报对应的参数,把实参的值赋值给形参。
  •         实参如果多于形参的个数:多传的参数就扬弃了
  •         实参如果少于形参的个数:没有传的参数,值就是undefined。(容易出题目)
           
  1. //函数形参实参个数匹配
  2. function getSum(num1,num2) {
  3. console.log(num1 + num2);
  4. }
  5. // 1.如果实参的个数和形参的个数一致,则正常输出结果
  6. getsum(1,2);
  7. // 2.如果实参的个数多于形参的个数     会取到形参的个数(多余参数不执行)
  8. getsum(1,2,3);
  9. // 3.如果实参的个数小于形参的个数     多于的形参定义为undefined   最终的结果就是NaN
  10. //形参可以看做是不用声明的变量num2是一个变量但是没有接受值﹑结果就是undefined
  11. getSum(1);                          // NaN
  12. //建议我们尽量让实参的个数和形参相匹配
复制代码
10.4.2 小结

  •         函数可以带参数也可以不带参数
  •         声明函数的时间,函数名括号内里的是形参,形参的默认值为undefined调用函数的时间,函数名括号内里的是实参
  •         多个参数中心用逗号分隔
  •         形参的个数可以和实参个数不匹配,但是结果不可预计,我们只管要匹配

10.5 函数的返回值

10.5.1 return先容
当函数实验完的时间,我们渴望函数给我一些反馈(好比盘算的结果),这个时间可以让函数返回一些东西。也就是返回值。函数通过return返回一个返回值
  1. // 1.函数是做某件事大概实现某种功能     function cook( aru) {        console.log(aru);   //在函数内部写输出函数着实是不公道的    }    cook('大肘子');​//标准写法:    function cook( aru) {        return aru;    }    console.log( cook('大肘子'));​// 2.函数的返回值格式    function函数名(){        return须要返回的结果;    }   
  2. 函数名();//(1)我们函数只是实现某种功能,终极的结果须要返回给函数的调用者"函数名()"通过 return实现的//(2)只要函数碰到return 就把背面的结果返回给函数的调用者﹐函数名() = return背面的结果​//3.代码验证    function getResult(){        return 666;    }    getResult();                    // 相称于 getResult() = 666    console.log(getResult());    // 4.求恣意两个数的和    function getSum( num1,num2) {        return num1 + num2;    }    console.log(getSum(1,,2));  // 3
复制代码
返回值语法:
  1. //声明一个带返回值的函数
  2. function 函数名(形参1, 形参2, 形参...){
  3.  //函数体
  4.  return 返回值;
  5. }
  6. //可以通过变量来接收这个返回值
  7. var 变量 = 函数名(实参1, 实参2, 实参3);
  8. console.log(变量);    // 输出这个变量值
复制代码
函数的调用结果就是返回值,因此我们可以直接对函数调用结果举行使用。
示例代码1:
  1. // 计算 n1- n2之间所有数的乘积
  2. function getProduct(n1, n2) {
  3.    var product = 1;
  4.    for (var i = n1; i <= n2; i++) {
  5.        product *= i;
  6.    }
  7.    return product; // 返回计算的值
  8. }
  9. var pro = getProduct(1, 5); // 用变量pro接收一下返回的值
  10. console.log(pro);   // 120
复制代码
示例代码2:
  1. //利用函数求数组[5,2,99,100,66,88]中的最大数值。
  2.     function getArrMax( arr) {      // arr接受一个数组
  3.         var max = arr[e];
  4.         for (var i =1; i <= arr.length; i++){
  5.             if (arr[i]>max) {
  6.                 max = arr[i];
  7.             }
  8.         }
  9.         return max;
  10.     }
  11. var re = getArrMax([5,2,99,100,66,88]);
  12. console.log(re);
复制代码
10.5.2 return 注意事项

  •         return制止函数
  1. //函数返回值注意事项
  2. // 1. return终止函数I
  3.     function getsum(num1,num2) {
  4.         return num1 + num2;     // return后面的代码不会被执行alert('我是不会被执行的哦!')
  5.     }
  6.     console.log(getSum(1,2));
复制代码

  •         return只能返回一个值
  1. // 2. return只能返回一个值
  2.     function fn(num1, num2) {
  3.         return num1,num2;//返回的结果是最后一个值
  4.     }
  5.     console.log(fn(1,2));
复制代码

  •         return可以用数组的方法返回多个值
  1. // 3.我们求任意两个数的加减乘数结果
  2.     function getResult(num1,num2){
  3.         return [num1 + num2, num1 - num2,num1 * num2, num1 / num2];
  4.     }
  5.     var re = getResult(1,2);    //返回的是一个数组console.log(re);
复制代码

  •         函数没有return返回undefined
            函数都是有返回值的

    •                 如果有return则返回return背面的值
    •                 如果没有return则返回undefined

  1.     function fun1() i
  2.         return 666;
  3.     }
  4.     console.log(fun1());    //返回666
  5. ---------------------------------------------------------
  6.     function fun2() {
  7.     }
  8.     console.log(fun2());    //函数返回的结果是undefined
复制代码
10.5.3 break ,continue ,return的区别

  •         break:竣事当前的循环体(如for、while )
  •         continue :跳出本次循环,继承实验下次循环(如for、while )
  •         return : 不光可以退出循环,还可以大概返回return语句中的值,同时还可以竣事当前的函数体内的代码(即退出当前函数)

10.6 函数三要素

函数三要素包罗:

  •         函数名
  •         参数
  •         返回值
10.7 文档解释

关于文档解释,javascript中另有一种解释叫做文档解释,经常用在函数声明处,用来表明这个函数的作用。
文档解释: /** 这是文档解释 */
以后写的函数的声明,都应该加上文档解释,方便阅读
示例代码:
  1. /**
  2. * 求圆的面积
  3. * @param r {number} 圆的半径
  4. * @returns {number} 圆的面积
  5. */
  6. function getArea (r) {
  7.    return Math.PI * r * r;
  8. }
复制代码
10.8 arguments的使用

当我们不确定有多少个参数通报的时间,可以用arguments来获取。在JavaScript中,arguments实际上它是当前函数的一个内置对象。全部函数都内置了一个
arguments对象,arguments对象中存储了通报的全部实参
arguments展示情势是一个伪数组,因此可以举行遍历。伪数组具有以下特点:

  •         具有length属性
  •         按索引方式储存数据
  •         不具有数组的push , pop等方法
注:只有函数才有arguments对象,而且是每个函数都内置好了这个arguments
  1. // arguments的使用
  2.     function fn() {
  3.         console.log(arguments);             //里面存储了所有传递过来的实参    arguments = [1,2,3]
  4.         console.log(arguments.length);
  5.     }
  6.     fn(1,2,3);
复制代码
运算结果:
正在上传…重新上传取消
获取数组内里某一个元素的方法:
  1. function fn() {
  2.      console.log(arguments[2]);    // arguments[索引号]
  3.    }
  4.    fn(1, 2, 3, 4, 5);
复制代码
运算结果:
正在上传…重新上传取消
按照数组的方式遍历arguments:
  1. function fn() {
  2.      for (var i = 0; i < arguments.length; i++) {
  3.        console.log(arguments[i]);
  4.      }
  5.    }
  6.    fn(1, 2, 3);
  7.    fn(1, 2, 3, 4, 5);
复制代码
运算结果:
正在上传…重新上传取消
10.9 函数综合训练

1. 使用函数求恣意个数的最大值
  1.    function getMax() {
  2.      var max = arguments[0];
  3.      for (var i = 1; i < arguments.length; i++) {
  4.        if (arguments[i] > max) {
  5.          max = arguments[i];
  6.        }
  7.      }
  8.      return max;
  9.    }
  10.    console.log(getMax(1, 2, 3));
  11.    console.log(getMax(1, 2, 3, 4, 5));
  12.    console.log(getMax(21, 2, 71, 666, 5, 100));
复制代码
运算结果:
正在上传…重新上传取消
2. 使用函数封装方式,翻转恣意一个数组
  1.    //利用函数翻转任意数组 reverse翻转
  2.    function reverse(arr) {
  3.      var newArr = [];
  4.      for (var i = arr.length - 1; i >= 0; i--) {
  5.        newArr[newArr.length] = arr[i];
  6.      }
  7.      return newArr;
  8.    }
  9.    var arr1 = reverse([9, 7, 5, 3, 1]);
  10.    console.log(arr1);
  11.    var arr2 = reverse(['red', 'green', 'blue', 'yellow']);
  12.    console.log(arr2);
复制代码
运算结果:
正在上传…重新上传取消
3. 使用函数封装方式,对数组排序 -- 冒泡排序
  1.    //利用函数冒泡排序sort排序
  2.    function sort(arr) {
  3.      for (var i = 0; i < arr.length - 1; i++) {
  4.        for (var j = 0; j < arr.length - i - 1; j++) {
  5.          if (arr[j] > arr[j + 1]) {
  6.            var temp = arr[i];
  7.            arr[j] = arr[j + 1];
  8.            arr[j + 1] = temp;
  9.          }
  10.        }
  11.      }
  12.      return arr;
  13.    }
  14.    var arr1 = sort([1, 5, 2, 9]);
  15.    console.log(arr1);
  16.    var arr2 = sort([12, 7, 66, 999]);
  17.    console.log(arr2);
复制代码
运算结果:
正在上传…重新上传取消
4. 求恣意数的阶乘(从1到n的积)
  1. function getProduct (n){
  2.    var product = 1;
  3.    for(var i = 1; i <= n; i++){
  4.       product *= i;
  5.    }
  6.    return product;
  7. }
  8. console.log(getProduct(5));  // 120
  9. console.log(getProduct(3));  // 6  
复制代码
5. 求恣意数组中的最大值与最小值
  1. function getMaxAndMin(arr) {
  2.    var max = arr[0];
  3.    var min = arr[0];
  4.    for (var i = 0; i < arr.length; i++) {
  5.        if (max < arr[i]) {
  6.            max = arr[i];
  7.        }
  8.        if (min > arr[i]) {
  9.            min = arr[i];
  10.        }
  11.    }
  12.    return [max, min]; // 返回一个数组
  13. }
  14. console.log(getMaxAndMin([11, 45, 59, 12, 8, 36, 14, 25]));  // [59 8]
复制代码
10.10函数的作用域

在函数中,只有全局作用域和函数作用域,由于在if、while、for等语句中界说的变量都是全局变量。
全局变量: 在最外层声明的变量就是全局变量,全局变量在任何地方都能访问的到。
局部变量: 在函数中声明的变量,就是局部变量,局部变量只有在当前函数体内可以大概访问。
隐式全局变量: 没有使用var界说的变量也是全局变量。
作用域: 变量可以发挥作用的地区
全局作用域: 在script标签内,函数外界说的作用域就是全局作用域。在全局作用域中界说的变量都是全局变量。
函数作用域: 在函数中的地区叫做函数作用域,在函数作用域中界说的变量就是局部变量,只能在当前函数内访问。
10.11 预剖析

js剖析器实验js代码的时间,分为两个过程:预剖析过程和代码实验过程
预剖析过程:

  •         把变量的声明提拔到当前作用域的最前面,只会提拔声明,不会提拔赋值。
  •         把函数的声明提拔到当前作用域的最前面,只会提拔声明,不会提拔调用。
  •         先提拔var,再提拔function
预剖析例题:
第一题:
  1. console.log(a);    // 打印a这个函数整体
  2. var a = 1;
  3. function a(){
  4. console.log("呵呵");
  5. }
  6. console.log(a);    // 1
  7. // 预解析后为
  8. /**
  9. var a;
  10. function a(){
  11.    console.log("呵呵");
  12. }
  13. console.log(a);    // 打印a这个函数整体
  14. a = 1;
  15. console.log(a);    // 1
  16. */
复制代码
第二题:
  1. var num = 10;
  2. fn1();
  3. function fn1() {
  4.    //在函数调用的时候,这个函数也会做预解析操作。
  5.    console.log(num);   // undefined
  6.    var num = 20;
  7.    console.log(num);   // 20
  8. }
  9. console.log(num);       // 10
  10. // 预解析后为
  11. /**
  12. var num ;
  13. function fn1() {
  14.    var num;
  15.    console.log(num);   // undefined
  16.    num = 20;
  17.    console.log(num);   // 20
  18. }
  19. num = 10;
  20. fn1();
  21. console.log(num);       // 10
  22. */
复制代码
第三题:
  1. var a = 18;
  2. var b = 30;
  3. fn();
  4. function fn() {
  5.    var b = 9;
  6.    console.log(a); // undefined
  7.    console.log(b); // 9
  8.    var a = 20;
  9. }
  10. // 预解析后为
  11. /**
  12. var a;
  13. var b;
  14. function fn() {
  15.    var b;
  16.    b = 9;
  17.    var a;
  18.    console.log(a);     // 自己作用域里有的就不要出去找
  19.    console.log(b);     // 9
  20.    a = 20;
  21. }
  22. a = 18;
  23. b = 30;
  24. fn();
  25. */
复制代码
第四题:
  1. fn();
  2. var b = 10;
  3. console.log(c); // 9
  4. console.log(b); // 10
  5. console.log(a); // 报错
  6. function fn() {
  7.    var a = 9;
  8.    b = 9;
  9.    c = 9;
  10.    console.log(a); // 9
  11.    console.log(b); // 9
  12.    console.log(c); // 9
  13. }
  14. // 预解析之后
  15. /**
  16. var b;
  17. function fn() {
  18.    var a;
  19.    a = 9;
  20.    b = 9;
  21.    c = 9;
  22.    console.log(a); // 9
  23.    console.log(b); // 9
  24.    console.log(c); // 9
  25. }
  26. fn();
  27. b = 10;
  28. console.log(c); // 9
  29. console.log(b); // 10
  30. console.log(a); // 报错
  31. */
复制代码
第五题:
  1. function fn() {
  2.    console.log(num1);  // undefined
  3.    console.log(num2);  // undefined
  4.    console.log(num3);  // 30
  5.    var num1 = 10;
  6.    var num2 = 20;
  7.    num3 = 40;
  8.    console.log(num1);  // 10
  9.    console.log(num2);  // 20
  10.    console.log(num3);  // 40
  11. }
  12. var num1 = 20;
  13. var num3 = 30;
  14. fn();
  15. console.log(num1);      // 20
  16. console.log(num3);      // 40
  17. console.log(num2);      // 报错
  18. // 预解析之后
  19. /**
  20. var num1;
  21. var num3;
  22. function fn() {
  23.    var num1;
  24.    var num2;
  25.    console.log(num1); // undefined
  26.    console.log(num2); // undefined
  27.    console.log(num3); // 30
  28.    num1 = 10;
  29.    num2 = 20;
  30.    num3 = 40;
  31.    console.log(num1); // 10
  32.    console.log(num2); // 20
  33.    console.log(num3); // 40
  34. }
  35. num1 = 20;
  36. num3 = 30;
  37. fn();
  38. console.log(num1); // 20
  39. console.log(num3); // 40
  40. console.log(num2); // 报错
  41. */
复制代码
10.12 递归函数

函数直接大概间接调用自己,必须要留出口,否则就调死了
示例代码:
  1. // 用递归求1-100的和
  2. /*
  3.    之前封装过一个getSum的函数比如getSum(100),就是求的1-100的和
  4.    现在我们可以这样理解:
  5.    1-100的和我们可以看做是 100 + getSum(99)
  6.    getSum(99) 可以看成 99 + getSum(98)。。。
  7.    依次这样推下去,但是要注意,到getSum(1)的时候,要留出口,否则会一直死循环下去
  8. */
  9. function getSum(n) {
  10.    if (n == 1) {       // 一定要留出口
  11.        return 1;
  12.    }
  13.    return n + getSum(n - 1);
  14. }
  15. console.log(getSum(100));
复制代码
10.13 回调函数

回调函数:把函数当成参数来使用,那么这个函数就叫回调函数。函数也是一种数据范例
示例代码:
  1. /*
  2. 思考,之前封装了一个bubbleSort排序的函数,但是只能排元素是数字的数组
  3. 现在想要判断字符串的长度,或者对象的属性的时候就很麻烦,就需要重新写一个函数
  4. 比如字符串长度,就需要是arr[j].length - arr[i+1].length
  5. */
  6. function bubbleSort(arr, fn) {
  7.    for (var i = 0; i < arr.length; i++) {
  8.        var flag = true;
  9.        for (var j = 0; j < arr.length - 1 - i; j++) {
  10.        
  11.            // 传一个函数进来,并且将arr[j], arr[j + 1]作为两个参数传进去
  12.            if (fn(arr[j], arr[j + 1]) > 0) {
  13.                flag = false;
  14.                var temp = arr[j];
  15.                arr[j] = arr[j + 1];
  16.                arr[j + 1] = temp;
  17.            }
  18.        }
  19.        if (flag) {
  20.            break;
  21.        }
  22.    }
  23. }
  24. // 纯数字数组
  25. var arr = [4, 3, 1, 6, 22, 21, 41, 4];
  26. // 调用的时候,我们需要将fn函数的两个参数也传进去
  27. // 这种把一个函数作为参数传进另一个函数的方式就叫回调函数
  28. bubbleSort(arr, function(a, b) { // a b 就相当于 arr[j] 和 arr[j+1]
  29.    return a - b;
  30.    // 如果是 return b - a 就相当于,上面的 arr[j+1] - arr[j]>0 那么就是从大到小排序
  31. });
  32. console.log(arr);
  33. // 封装后的排序函数也可以直接根据字符串的长度进行排序了
  34. var arrStr = ["aaa", "bb", "cccc", "d"];
  35. bubbleSort(arrStr, function(a, b) {
  36.    // 因为传进去的是一个函数,arr[j] 和 arr[j+1]是以两个参数的形式传进去的
  37.    // 当数组元素是字符串的时候,就可以进行.length操作了
  38.    return a.length - b.length;
  39. });
  40. console.log(arrStr);
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表