芳心粽伙饭头像
关注
JavaScript第四章 函数封面图

JavaScript第四章 函数

4. 函数(重)

4.1 函数基础

函数:一种结构报过一段具备功能性的代码,以便下次使用时直接调用即可(代码复用性)

  • 函数结构

    function 函数名([参数]){

    ​ 函数体

    ​ [return 返回值]

    }

  • 访问函数:函数名(参数)

    // 案例1:定义一个函数,实现输出一句话输出3次
    function sayThree(word){
        for(var i=0;i<3;i++){
            alert(word);
        }
    }
    sayThree("hello world");

    // 案例2:计算两个数之积
    function getMul(a,b){
        return a*b;
    }
    console.log(getMul(2,3));
  • 函数参数问题

    • 参数可以为0个、1个或多个

    • 形参和实参问题

      • 形参:函数在定义时写的参数,在内存中没有实际的存储空间
      • 实参:函数在调用时传递的参数,在内存中就实际存在的
    • 局部变量和成员变量

      作用域:某一变量/对象/函数的作用范围

      • 局部变量:写在函数内部的变量
      • 成员变量:写在函数外部的变量
    • 默认值参数

      • 格式:函数定义时,通过“参数=值”的形式定义
      • 默认值参数必须写在普通参数之后
      • 调用函数时,可以不用传递默认值参数
      • 如果需要改变默认值参数,则使用“参数名(必须与定义时保持一致)= 新值”的形式临时改变默认值
        // 默认值参数
        function getMul(r,PI=3.14){
            return PI*r*r;
        }
        console.log(getMul(3));
    
    • 值传递和引用传递
      • 值传递:给函数参数赋值
      • 引用传递:传递参数是传递的内容为引用(对象)
        // 引用传递测试
        var arr=[1,5,3,4,2];
        console.log(arr);
        function arrSort(arr) {
            return arr.sort((a,b)=>a-b);
        }
        console.log(arrSort(arr));
    
    • 函数的参数为函数(函数高阶用法)

      将函数对象作为参数传递,且在函数的内部可以执行(函数名())参数函数

        // 函数的参数为函数
        function testFn(){
            alert("hello world");
        }
        function printWord(fn){
           fn();
        }
        printWord(testFn);
    
    • arguments 对象

      可以通过 arguments 对象获取当前函数的参数

        sum(10,22);
        function sum(a,b){
            console.log(arguments);
            console.log(arguments[0]);
            console.log(arguments[1]);
        }
    

    在这里插入图片描述

    • 函数提升问题:JS在编译时,会检索所有的函数定义,并加载(即使函数定义写在函数下方,也是可以正常执行的)
  • 函数返回值问题

    • 基本函数返回值
      • 当函数有返回值时,需要使用 return
      • 在调用函数时,需要变量接收 return 返回的返回值
    • 函数返回值为函数
        // 函数返回值为函数
        function test1(){
            alert("test1");
        }
        function test2(){
            return test1;
        }
        var res = test2();
        res();
    
    1. 函数返回值为函数时,返回的内容必须为已定义函数名
    2. 使用函数时,可以使用任意变量接受返回的函数对象
    3. 再通过变量()访问返回的函数
  • 函数调用过程

    1. 实际为 压栈 的过程
    2. 函数在调用时,会在栈中开辟栈帧,栈帧中存储函数的局部变量,栈帧随函数调用而创建,随函数结束而销毁
    3. 局部变量生命周期:函数调用时创建,函数结束执行时销毁
  • ES6新特性结构语法

    一句话:快速从数组 / 对象中提取值,赋值给变量

    1. 对象解构(最常用)
    • 基础
    const user = { name: "张三", age: 18 };
    // 解构
    const { name, age } = user;
    console.log(name, age); // 张三 18
    

    变量名必须和对象属性名一致

    • 设置默认值
    const user = { name: "张三" };
    const { name, age = 20 } = user;
    // age不存在,自动取默认值20
    
    • 重命名(属性名和变量名不一样)
    const user = { name: "张三" };
    const { name: username } = user;
    // 把name属性取出,存入变量username
    console.log(username);
    
    • 函数参数解构(⚠面试高频)
    // 传入对象,直接在形参解构
    function show({name, age}){
      console.log(name, age)
    }
    show({name:"李四", age:22})
    
    1. 数组解构
    • 按下标顺序取值,名字随便写
    const arr = [10,20,30];
    const [a,b,c] = arr;
    console.log(a,b,c) //10,20,30
    
    • 跳过某些项,用逗号占位
    const arr = [10,20,30];
    const [a,,c] = arr;
    console.log(a,c) //10,30
    
    • 默认值
    const arr = [10];
    const [a,b=99] = arr
    console.log(b) //99
    
    • 剩余运算符 ...rest(只能放最后!)
    const arr = [1,2,3,4]
    const [first, ...other] = arr
    console.log(other) // [2,3,4]
    
    1. 字符串也可以解构(当成字符数组)
    const str = "abc";
    const [x,y] = str;
    console.log(x,y) // a b
    

    ⚠️重点坑点

    1. 对象解构:变量名匹配属性名,和顺序无关;数组解构按顺序,变量名随意
    2. ...rest 剩余参数只能写在最后,写前面直接报错
    3. 解构{}开头,单独一行会报错!JS会当成代码块:
    // ❌错误写法
    {name} = user
    // ✅要加括号
    ({name} = user)
    
    1. 默认值只有当值为 undefined 的时候才生效,null不会触发默认值

    📝面试简答

    解构赋值是ES6语法,分为对象解构和数组解构。 对象解构:根据属性名提取属性值;数组解构:按索引顺序提取元素。支持默认值、变量重命名、剩余运算符...;常用于函数参数快速提取数据,简化代码。

    📌补充:... 两个身份(区分)

    • 剩余:解构里 const [a,...rest],收集剩下的值
    • 展开:const arr2 = [...arr1] 展开数组(不是解构,容易混)

    练习题:

    const obj = {id:1, msg:"ok"}
    const { id, msg:info, type="test" } = obj
    console.log(id, info, type)
    

    输出是什么?

4.2 lambda(箭头函数)及匿名函数

  • 匿名函数:无名的函数

    • 作用
      • 闭包(JS中的重要语法)
      • 函数的回调(递归)
      • 函数的立即执行
  1. 匿名函数作为参数传递
    // 匿名函数
    // function setName(){
    //     return "zhangsan";
    // }
    function testFn(fn){
        alert("user:"+fn());
    }
    // 参数作为一个匿名函数
    testFn(function(){
        return "zhangsan";
    });
  1. 匿名函数常见写法①——引用传递过程
    var testFn = function(){
        alert("lisi");
    }
    testFn();
  1. 立即执行的匿名函数(主要作用:创建私有作用域变量,防止变量污染)
    (function(){
        alert("hello world");
    })();
  • 箭头函数(lambda):简化函数写法
// 箭头函数
function show(){
    alert("hello world");
}
show();

// 1.无参——当函数只有一句代码体,{}可以省略
var show = ()=>{
    alert("hello world");
}
show();

// 2.单参——当函数只有一个参数时,()可以省略
var show1 = (username)=>alert("username:"+username);
show1("zhangsan");

// 3.多参
var show2 = (a,b)=>{
    alert(a+b);
}
show2(10,20);

// 4.多条语句
var show3 = (a,b)=>{
    alert(a+b);
    alert(a-b);
}
show3(10,20);

4.3 闭包(closurd)

函数的嵌套中,内部函数访问外部函数的一种结构,内部函数可以访问外部函数定义的变量。


  • 条件
    • 函数的嵌套
    • 内部函数访问外部函数的成员

  • 特点
    • 内部函数可以访问外部函数的变量或参数
    • 外部函数的变量或参数在内部执行完毕后仍然保存在内容中,不被垃圾回收

  • 缺点
    • 函数的局部变量在调用完没有被及时回收,占用内存时间会变长
    • 内存泄漏:没有被回收的变量积攒过多而导致内存溢出
    • 积攒过多后会抛出异常

  • 应用

    所有数据和功能封装在一个函数的内部(私有作用域),只向外部暴露一个接口

    function outer(){
        let username="zhangsan";
        // 内部函数
        function inner(){
            alert(username);
        }
        return inner;
    }
    var res = outer(); //引用传递
    res();
  1. 将函数的参数传递给内部函数调用
    function showDialog(time,msg){
        setTimeout(()=>{
            alert(msg);
        },time);
        // 有两个参数,第一个参数为需要执行的函数,第二个参数为执行时间
    }
    showDialog(2000,"2秒后跳转");
  1. 可以通过立即执行函数将功能后局部变量私有化,提供外部访问的接口
    (() => {
        var username="张三";
        function showUsername(){
            alert("SVIP:"+username);
        }

        window.myFun = {test:showUsername}

    })();
    myFun.test();

4.4 递归

eg:画中画、梦中梦、套娃……


函数返回自身的一种技术,主要处理复杂的算法问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>递归函数</title>
</head>
<body>
    
</body>
</html>
<script>
    // 案例:计算阶乘
    function factorial(n){
        if(n==1){
            return 1;
        }
        return n*factorial(n-1);
    }
    console.log(factorial(5));
</script>

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/2401_89563276/article/details/166596868

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--