【前端JS交互篇】函数、参数、返回值、闭包函数、递归函数、内存、模块化编程

一、函数的声明与调用

1.1 函数概述

函数可以封装一些功能,可以供外部去重复的调用。所以,一般我们把函数叫做具有重复功能的代码块。

JavaScript 基础到高级
Canvas游戏开发
原生JavaScipt案例合集
JavaScript +DOM基础

假设饭店就是一个函数,饭店的功能就是做各种各样的菜,但是具体做什么菜,需要用户来点,用户可以是我们当中的任何一个人,当我们点好菜付完帐,那么饭店就行驶它做饭的功能,开始为我们做指定的可口饭菜,这个我们点餐的过程,其实就是类似于函数调用的过程。最后,饭店做完菜给我们呈上来,这个菜就类似于函数返回的数据

1.2 函数的声明

函数使用关键字 function 来进行声明

在声明的函数内部,我们可以书写一些代码,使这个函数具有某一种特定的功能。在函数内部书写的代码我们习惯上称为函数体。

函数声明的语法格式:

function 函数名(形式参数){函数体
}

思考:求任意两个数的和

函数名的命名规则:同变量命名规则

1.3 函数的调用

函数声明后,不会自动执行,需要进行调用

函数调用的语法 函数名()

函数的调用方式

  • 直接在 JS 脚本的任何为止进行调用 函数名()
  • 事件驱动

练习:使用函数包装流程语句,也就是将流程语句当作函数体。一个大于0的整数,打印它的所有约数。

分析:一个数它的最小约数是1,最大约数是它本身。如果还有其它约数,肯定在 1 和 它本身之间。

什么是约数?

约数,又称因数。整数a除以整数b(b≠0) 除得的商正好是整数而没有余数,我们就说a能被b整除,或b能整除a。a称为b的倍数,b称为a的约数。

使用函数封装,简单介绍几个好处:

  • 避免全局变量的污染;
  • 节约内存;
  • 提高程序的执行效果;
  • 减少重复代码的书写;
  • 便于后期维护;
  • 可以返回数据进行二次操作;
    等等…

1.4 函数的类型

function f(){}
console.log(typeof f);//function

二、函数的参数

2.1 函数参数概念

参数可以类似的看作我们之前声明的变量,只不过它的位置在函数后面的小括号中,且不需要再使用var进行声明。函数的参数分为两种:形式参数 和 实际参数。

**形式参数:**简称形参。在函数声明的时候,小括号中给定的参数,此时,不能确定参数的数据类型 和 具体的值。类似于前面讲的去饭店服务员给我们的菜单,可以提供给这么多菜,但是具体做什么菜还需要客户指定。

**实际参数:**简称实参。在函数调用的时候,用来替换形参的具体的值(传递的参数),此时确定了数据类型和值。

类似于前面讲的去饭店点菜,根据服务员提供的菜单,点具体的菜名

**传参:**函数调用,有一个传递参数的过程,这个过程我们叫它传参。

需求:求一个大于0的整数,约数的个数

通过上面的描述和演示,总结出JS的另外一个特点:

JS是一门动态的、弱类型语言。

2.2 函数的重载

重载可以看作是函数参数的应用。

函数的重载:在一个程序中,声明多个同名函数,但是其数据类型以及参数的个数并不相同。

JS中不存在函数重载的概念,我们只能模拟。因为一旦在JS中声明多个同名函数,后面的会覆盖前面的。

2.3 arguments对象

arguments对象是JS中一个特殊的对象。它是一个类数组,存储的是函数调用时所有传递的实际参数。

arguments对象中内置了一个 length 属性,用来获取函数调用时实际传递的参数的个数 语法 arguments.length

类数组和数组都具有索引,索引从0开始,依次递增,如上图:arguments对象中,有对应的索引,一一对应于传递的参数。通过 arguments[索引] 可以获取执行的对应的参数值:

​ 获取第一个参数 arguments[0]

​ 获取最后一个参数 arguments[arguments.length - 1]

function sum() {console.log("arguments:",arguments);console.log("函数调用时传递的第一个参数:",arguments[0]);console.log("函数调用时传递的参数个数:",arguments.length);console.log("函数调用时传递的最后一个参数:",arguments[arguments.length - 1]);
}

模拟函数的重载

三、函数的返回值

很多情况下,我们封装函数的目的是为了利用函数的这个功能,得到某些数据,然后对这些数据进行二次操作。

那么,如果想要在函数中返回这些数据,那么需要用到关键字 return。

return 关键字用于在函数中返回数据,并跳出函数。

如果仅仅是为了跳出函数,而不需要返回任何数据,那么直接return即可。

练习: 判断一个大于0的数字是否是质数。

什么是质数?

​ 质数也叫素数,是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。

分析: 可以根据约数的个数,当约数的个数是2的时候,那么这个数就是质数。

return作为跳出函数用。一般会在面试中经常被问道,return、break、continue的区别?

四、函数的作用域

4.1 作用域概述

**概述:**当声明函数后,在函数的内部(大括号函数体位置)形成自己一个独立的内部区域,这个内部区域就叫做函数作用域。

函数作用域相对于整个脚本区域来讲,只是一个很小的独立区域,这个很小的区域我们通常叫它局部作用域。而整个脚本区域,我们通常叫它全局作用域。

全局作用域:函数外的区域叫做全局作用域;在全局作用域中声明的变量,可以在脚本的任何位置(包裹函数内)都可以对其进行调用,这个变量我们称为全局变量。全局变量的生命周期:从文件被执行时创建(当前就是页面被加载),页面关闭后销毁。

局部作用域:函数内的区域叫做局部作用域;在局部作用域中声明的变量,只能在函数的内部进行访问调用,那么此时我们称其为局部变量。局部变量的生命周期:函数被调用时创建,函数调用完毕销毁。

4.2 作用域链问题:

嵌套函数中,存在多个被声明的同名函数,在调用时,首先查看当前作用域是否有这个变量,有则调用,没有则去它的上一级作用域中查找,如果有则使用,如果没有,继续向上查找,直到找到为止

//声明一个全局变量 num
var num = 1;
function fn() {//在第一层函数中,声明一个变量 numvar num = 10;//在第一层函数中,声明一个内部函数 fn2//创建函数的另外一个方式  将声明的匿名函数赋值给一个变量var fn2 = function () {var num = 100;return num;}return fn2;
}

4.3 局部作用域内不使用var声明的变量

如果在函数的内部,不使用var声明,首先这是不标准的写法,一般不建议,且在严格摸下会报错。其次,如果我们不小心这样用了,那么在函数被调用后,这个变量会提升为全局变量。如果函数没有被调用,则不会创建这个变量。

function f() {num = 10;console.log("num:",num);
}

这种情况,很容器造成全局变量的污染,不建议使用。

var i = 2;
console.log('i:',i);//i: 2
function f1() {var i = 20;console.log('i:',i);//i: 20
}
f1();
console.log('i:',i);//i: 2var j = 3;
console.log("j:",j);//j:3
function f2() {j = 30;console.log("j:",j);//j:30
}
f2();
console.log("j:",j);//j:30

上面的 j 本身是想作为一个局部变量来处理,但是由于没有使用 var 声明,造成函数调用时,这个本要作为局部变量定义的变量 变成了 全局变量的赋值操作,这样就造成了全局变量的污染,或称为命名冲突。

4.4 同一个变量多次声明

如果在同一个作用域内,一个变量被多次声明,那么声明只会生效一次,以第一次声明为准,后面的声明不再作数,直接作为变量的赋值操作。

var num = 1;
console.log("num:",num);//num:1var num = 10;
console.log("num:",num);//num:10num = 100;
console.log("num:",num);//num:100

五、函数的提升

在 JS 中,有变量和函数的提升,JS引擎在解析代码时,分成两步:

  1. 预解析阶段:将所有变量 和 函数的声明,提升到当前作用域的最顶部
  2. 运行阶段:进行变量的赋值操作

在JS中,函数的创建方式有三种:

  • 第一种标准的方式 function 函数名(参数列表){函数体}

    function f() {num = 10;return "num:"+num;
    }
    
  • 第二种函数表达式的方式:将一个匿名函数赋值给一个变量 var f = function(参数列表){函数体}

    var f1 = function(){num = 10;return "num:"+num;
    }
    
  • 第三种内置对象的方式 var f = new Function(“参数列表”,“函数体”)

    var f3 = new Function("num = 10; return 'num:'+num");var f2 = new Function("a","b","return a+b");
    

使用标准的方式创建的函数,与其它两种方式在调用时的不同:

  1. 如果都是先声明,再去调用,看不出有什么区别:上面已经验证过 f() f1() f3() 结果一致

  2. 如果时先调用,再去声明的情况,那么结果就不同了,如下代码

    非标准的方式,利用的是一个变量来接收一个函数,那么其本质就是变量。前面讲过变量的提升,相当于将变量的声明提升到当前作用域的最顶部,这时还没有赋值,在调用的时候,变量的值是undefined。所以后面两种创建函数的方式,只能先声明再调用。

    **标准的方式:**会将整体作为一个声明部分,再预解析阶段,将其整体提升到当前作用域的最顶部,所以标准的方式创建的函数可以在当前作用域的任何为止被调用。

小问题:如果在同一个文件中,存在同名的变量 和 函数,函数优先于变量提升;而前面讲到,在一个文件中,声明多个变量,只有第一个会生效,而函数也可以看作是变量,不管使用var还是使用function都叫做声明。所以函数优先于变量提升后,其它变量的声明都变成了赋值操作。

六、模块化编程

假设有一个酒店:酒店中有保安负责安保、前台负责接待、服务生负责提供服务、厨师负责做饭、大堂经理负责协调等等。

这时,如果将安保、前台、服务生、厨师、协调等工作全部交给大堂经理一个人去做,这样效率会很慢,酒店几乎没有多久肯定会倒闭。此时,酒店提供所有的功能都在大堂经理一个人身上,肯定是不行。

这时,酒店考虑到经营问题,又招来了保安、前台等等人,负责其自己相应的领域工作,然后大堂经理只需要调配这些人即可。这样效果就会很高了。

那么,代码中也是一样,尽可能的减少代码的耦合性。我们可以利用函数,将功能封装的尽量单一,在不同的场景下,可以被重复的利用,优化了代码又提高了执行的效果。这些,其实就是模块化的思想。

后面随着课程的深入,我们会接触到 seajs、requirejs、nodejs 这些东西,都是用来进行模块化开发的,不同之处在于其将一个js文件作为一个模块,可以避免全局变量的污染。

这里,我们使用函数来体会模块化编程的思想。

人类从古至今,习惯将事情分工,将一些内容做成一些公共模块,模块可以重复反复使用。
模块化编程:将一些基础的公共的部分单独封装到一个函数内,可以多次被调用。

**案例:**输出100以内的质数,模块化编程。
逆向思维的过程:输出100以内的质数 → 判断是不是质数 → 找约数个数

练习:找100以内的完美数:(一个数的约数除了它本身外其他约数和还等于这个数)。
注意:模块化编程,可以让我们的程序更加优化,各个小模块要尽量功能单一,提高重复使用率。

**练习:**赢数是一种特殊的自然数,除去它本身以外所有的约数和大于其本身。请输出100以内所有的赢数

练习:如果整数 A 的全部约数(包括1,不包括 A 本身)之和等于 B,且 整数 B 的全部约数(包括1,不包括B 本身)之和等于 A,则称整数 A 和 B是一对亲密数。输出1000以内的亲密数。

七、作业

  1. 封装一个函数,实现功能:不借助临时变量,进行两个整数的交换。

    提示:运算符、函数有两个参数

  2. 封装一个函数,求3个数中的最大值

    提示:函数有三个参数、要求至少使用两种方式实现

  3. 封装一个函数,实现在页面上输出 100 ~ 1000之间所有的质数,并要求每行显示 6 个数字

  4. 封装一个函数,实现 12! - 10! 结果

    要求:不能使用递归

八、数据类型在内存中的位置

数据类型有两大类:基本数据类型 和 引用数据类型

  • 基本数据类型:Number数值类型 string字符串类型 Boolean布尔类型 Null空类型 Undefined未被定义的
  • 引用数据类型:Object对象类型、Function函数类型

基本数据类型存储在内存的栈中,引用数据类型存储在堆中

代码演示:

 var a = 10,b = 20,c = 30,fn = function () {};console.log("a:",a,"b:",b,"c:",c,"fn:",fn);//a: 10 b: 20 c: 30 fn: ƒ () {}//修改b的值
b = 200;
console.log("a:",a,"b:",b,"c:",c,"fn:",fn);//a: 10 b: 200 c: 30 fn: ƒ () {}//声明一个变量d来接收基本数据类型的变量cvar d = c;console.log("c:",c,"d:",d);//c: 30 d: 30//改变基本数据类型c的值c = 300;console.log("c:",c,"d:",d);//c: 300 d: 30
//总结:基本数据类型变量在进行赋值时,只是将变量保存的值复制了一份给另外一个变量进行赋值。此时变量值得改变不会互相影响。//声明一个变量,来接收引用数据类型得变量
var fn2 = fn;
console.log("fn:",fn,"fn2:",fn2);//fn: ƒ () {} fn2: ƒ () {}
console.log(fn === fn2);//true 指向同一个内存地址//改变其中一个引用数据类型的结构
fn.x = 100;
console.log("fn:",fn,"fn2:",fn2);//fn: ƒ () {} fn2: ƒ () {}
console.log(fn === fn2);//true 指向同一个内存地址
console.log("fn.x:",fn.x,"fn2.x:",fn2.x);//fn.x: 100 fn2.x: 100
//总结:引用数据类型变量在进行赋值时,将引用数据类型的变量保存的地址复制了一份给另外一个变量复制。此时两个变量指向同一个地址,其中一个结构发生改变会影响另外一个

九、递归函数

递归就是在函数的内部调用函数自己本身;

递归函数多用来解决一些 数字0以上 的数学问题;

递归函数必须给定一个条件,来退出函数,否则会造成内存堆栈溢出的问题。

如:

​ 累加问题 1 + 2 + 3 + … + 98 + 99 + 100

​ 累乘问题 100! = 100 * 99 * 98 * … * 3 * 2 * 1

​ 生兔子的问题 有一对兔子,三个月开始每个月生一对小兔子,这一对小兔子在成长到三个月的时候,每个月也是生一对小兔子,问一年之后,在没有死亡的情况下,总共有多少对兔子?

​ 换算成数学,就是一个斐波那契数列 1 1 2 3 5 8 13 21 34 55 89 144…

// 斐波那契数列  1  1  2  3  5  8  13  21  34  55 89  144...
console.log(feiBo(1));
console.log(feiBo(2));console.log(feiBo(11));
console.log(feiBo(12));
// 求斐波那契数列中第 N 项的值
function feiBo(n) {if(n === 1 || n === 2){return 1;}return feiBo(n - 1) + feiBo(n - 2);
}//feiBo(3) =  feiBo(3 - 1) + feiBo(3 - 2) = feiBo(2) + feiBo(1) = 1 + 1 = 2
//feiBo(4) =  feiBo(4 - 1) + feiBo(4 - 2) = feiBo(3) + feiBo(2) =  feiBo(3 - 1) + feiBo(3 - 2) + 1 = 1 + 1 + 1 = 3
//feiBo(5) = ....

十、匿名函数和自执行函数

匿名函数:也叫拉姆达函数,说白了就是没有名字的函数

自执行函数:IIFE,也叫立即执行函数。不需要进行调用,随着程序的执行会自动调用。IIFE有两部分组成,函数体和执行部分。

//匿名函数的使用
//1. 声明一个变量,来接收一个匿名函数
var f = function () {};//事件驱动  window窗口对象的点击事件
var count = 0;
window.onclick = function () {console.log("第" + (++count) +"次点击了窗口...")
};//IIFE自执行函数
;(function (a,b) {console.log(a + b);
})(10,20);var result = (function (a,b) {return a + b;
})(10,20);
console.log("result:",result);

十一、闭包函数

什么是闭包?

闭包就是一个函数可以访问另外一个函数内部的变量。

想要理解闭包,需要先了解 作用域链的问题 和 垃圾回收机制的问题(设置到变量的生命周期)。

在JS中,任何一个函数都可以认为是闭包;常见的情况是,函数中可以访问全局变量,嵌套函数可以访问祖先元素中的变量。

function f(){var i = 1;function f2(){console.log(i);}return f2;
}//f函数中的 变量i 是一个局部变量,局部变量只能在函数的内部被访问到
function f3(){console.log(i);
}

如果想要在一个函数的外部,访问这个函数内部的变量,那么该怎么操作?

假设,我们将嵌套在内部的函数作为一个联通内外的桥梁,在调用外层函数时,返回这个内部的函数

function f() {var i = 1;return function () {return i++;}
}console.log(f);
console.log(f());
console.log(f()());//1
console.log(f()());//1
//也就证明,每一次都是一个全新的环境,得到的值也是一样的  局部变量和函数在外部函数调用完毕后即销毁//那么,利用对象之间的引用关系,可以保存当时执行的一个环境,进而将局部的变量保存下来
//垃圾回收机制中:对存在引用关系的对象 不会进行回收
var test = f();//此时test就是一个函数
console.log(test)
console.log(test());//1
console.log(test());//2
console.log(test());//3var test2 = f();//此时又是一个新的闭包函数  当执行f()时,传递给test2的那个桥梁函数会记住当时所执行的上下文环境
console.log(test2);
console.log(test2());//1
console.log(test2());//2

闭包的问题:

闭包不宜使用过多,容易造成内存的泄漏问题;

但是,使用闭包可以避免全局变量的污染,很多高级程序中,都会有闭包的应用。后面在高级课,会利用闭包来私有化对象的属性和方法。

闭包目前可以用来解决:

​ 循环中,有异步语句存在的情况下,无法正确获取索引的问题。

// console.log(1111);
//回调函数:将一个函数作为另外一个函数的参数
//在JS中,有一个内置的延迟器,在指定时间后,去执行相应的操作
// setTimeout(function () {
//     console.log(2222);
// })
// console.log(3333);//循环中,异步语句,获取索引的问题
// for (var i = 0; i < 10; i++) {
//     console.log("i:",i);
// }for (var i = 0; i < 10; i++) {(function (j) {setTimeout(function () {console.log("内j:",j);})})(i);
}
console.log("外i:",i);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/11496.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows下搭建php开发环境

http://wed.xjx100.cn/news/139397.html?actiononClick https://www.bilibili.com/read/cv23429835/ https://www.php.cn/faq/498307.html 安装iis 选择卸载程序 安装php 官网https://www.php.net/下载 选择线程安全 国内地址 下载完成后解压放到想存放的路径 添加p…

数据可视化 - 动态柱状图

基础柱状图 通过Bar构建基础柱状图 from pyecharts.charts import Bar from pyecharts.options import LabelOpts # 使用Bar构建基础柱状图 bar Bar() # 添加X轴 bar.add_xaxis(["中国", "美国", "英国"]) # 添加Y轴 # 设置数值标签在右侧 b…

深入浅出之Docker Compose详解

目录 1.Docker Compose概述 1.1 Docker Compose 定义 1.2 Docker Compose产生背景 1.3 Docker Compose 核心概念 1.4 Docker Compose 使用步骤 1.5 Docker Compose 常用命令 2. Docker Compose 实战 2.1 Docker Compose下载和卸载 2.2 Docker Compose 项目概述 2.3 Do…

OpenStack之云主机管理

一&#xff09;必备知识 1.云主机与快照管理 a-云主机管理 云主机管理是OpenStack云计算平台的核心功能&#xff0c;通常&#xff0c;云主机的管理包括创建、删除、查询等。可使用以下命令对OpenStack的云主机进行管理&#xff1a; openstack server <操作><云主机…

腾讯云从业者认证考试考点——云计算基础

文章目录 云计算发展历史云计算技术架构&#xff08;两3两4&#xff09;云计算的4种模式云计算的3种服务模式云计算的3种关键技术计算虚拟化技术网络虚拟化技术分布式数据存储技术云计算管理平台 云计算的4层架构 云计算的影响业务主流云产品 云计算发展历史 腾讯云机房达到的…

北航投资已投企业四象科技成功发射三颗卫星

1箭4星&#xff01;2023年7月23日10时50分&#xff0c;我国在太原卫星发射中心使用长征二号丁运载火箭&#xff0c;成功将四象科技“矿大南湖号”SAR遥感卫星、“虹口复兴号”光学遥感卫星、“中电农创号”热红外遥感卫星以及银河航天灵犀03星共4颗卫星发射升空&#xff0c;卫星…

idea springBoot 部署多个项目打开Run Dashboard 窗口

在部署springcloud 项目的时候 本地调试&#xff0c;有可能需要全部启动所有服务&#xff0c;单个部署比较麻烦&#xff0c;通过Run DashBoard 窗口可以完美实现 1.先打开项目的文件地址找到workspace.xml文件&#xff0c;在项目下的.idea\workspace.xml 2. ctrlf 找到RunDash…

SpringMVC-mybatis,SQL语句中误用了desc关键字,导致报错。

17-Jul-2023 21:26:22.295 淇℃伅 [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.ApplicationContext.log 1 Spring WebApplicationInitializers detected on classpath 17-Jul-2023 21:26:22.621 淇℃伅 [RMI TCP Connection(2)-127.0.0.1] org.apache.catalin…

小白的机器学习之路(四)神经网络的初步认识:基于pytorch搭建自己的神经网络

小白的机器学习之路&#xff08;四&#xff09; 引子神经网络的基本结构反向传播算法和激活函数优化器如何通过pytorch搭建自己的BP network 引子 当前交通大数据业务的需要&#xff0c;需要承担一部分算法工作&#xff08;数据处理&#xff09;&#xff0c;考虑到上次研究深度…

springboot开放实验室管理系统【纯干货分享,免费领源码03361】

摘 要 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是使用动态网页开发技术java作为系统的开发语言&#xff0c;M…

大数据课程C3——ZooKeeper的概述

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 了解Zookeeper的特点和命令&#xff1b; ⚪ 了解Zookeeper的构成部分ExecutorService、Lock、Atomic&#xff1b; 一、ExecutorService-执行器服务 1. ForkJoinPool-分…

【Leetcode】二叉树进阶面试题

文章目录 二叉树创建字符串二叉树分层遍历&#xff08;从前开始&#xff09;二叉树分层遍历&#xff08;从后开始&#xff09;二叉树的最近公共祖先二叉搜索树与双向链表从前序与中序遍历序列构造二叉树从中序与后序遍历序列构造二叉树二叉树的前序遍历&#xff08;非递归&…

GitLab 删除项目

1.点击头像 2.点击Profile 3.选择要删除的项目点进去 4.settings-general-Advances-expand 5.然后在弹出框中输入你要删除的项目名称即可

Java - 注解开发

注解开发定义bean Component的衍生注解 Service&#xff1a; 服务层的注解 Repository&#xff1a; 数据层的注解 Controller&#xff1a; 控制层的注解 纯注解开发 bean管理 bean作用范围 在类上面添加Scope(“singleton”) // prototype: 非单例 bean生命周期 PostCon…

关于Spring的bean的相关注解以及其简单使用方法

一、前置工作 第一步&#xff1a;创建一个maven项目 第二步&#xff1a;在resource中创建一个名字叫做spring-config.xml的文件&#xff0c;并把以下代码复制粘贴 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.sprin…

用flask run代替flask run --debug

安装python-dotenv依赖。 在项目根目录下新建.flaskenv文件&#xff0c;并作如下配置&#xff1a; FLASK_ENVdevelopment FLASK_DEBUG1

redis-cluster 创建及监控

集群命令 cluster info&#xff1a;打印集群的信息。 cluster nodes&#xff1a;列出集群当前已知的所有节点&#xff08;node&#xff09;的相关信息。 cluster meet <ip> <port>&#xff1a;将ip和port所指定的节点添加到集群当中。 cluster addslots <slot…

《Federated Unlearning via Active Forgetting》论文精读

文章目录 1、概述2、方法实验主要贡献框架概述 3、实验结果比较方法实验结果忘却完整性忘却效率模型实用性 4、总结 原文链接&#xff1a; Federated Unlearning via Active Forgetting 1、概述 对机器学习模型隐私的⽇益关注催化了对机器学习的探索&#xff0c;即消除训练数…

[React]常见Hook实现之useUpdateLayoutEffect

[React]常见Hook实现之useUpdateLayoutEffect useUpdateLayoutEffect是一个自定义的React Hook&#xff0c;它与useUpdateEffect类似&#xff0c;都是用来在组件更新时执行副作用函数。不同的是&#xff0c;useUpdateLayoutEffect使用的是useLayoutEffect来注册副作用函数。 …

基于JAVA SpringBoot和Vue高考志愿填报辅助系统

随着信息技术在管理中的应用日益深入和广泛&#xff0c;管理信息系统的实施技术也越来越成熟&#xff0c;管理信息系统是一门不断发展的新学科&#xff0c;任何一个机构要想生存和发展&#xff0c;要想有机、高效地组织内部活动&#xff0c;就必须根据自身的特点进行管理信息时…