函数闭包
函数表达式
函数声明:(函数声明提升)
function person(){}
函数表达式:(必须在调用之前声明)
var person = function(){}
递归函数:
一个函数通过名字调用自身
function fac (num) { // 阶乘递归
if (num <=1) {
return 1
} else {
return num*fac(num-1);
}
}
var a = fac;
fac = null;
console.log(a(4)) ; // 出错 因为fac在函数中调用自身时fac = null
为了做到松耦和:
非严格模式下使用argument.callee(指向正在执行的函数指针)来解决。
function fac (num) { // 阶乘递归
if (num <=1) {
return 1
} else {
return num*argument.callee(num-1); /
}
}
另一种方式:
var ff = (function f(num){
if (num <=1) {
return 1
} else {
return num*f(num-1); // 即使ff = null f(num-1)还是可以访问到
}
})
闭包:
定义:当一个函数内部定义了一个函数就创建了闭包,闭包有权访问包含函数内部的全部变量。
function a () {
var arr = [];
for (var i = 0,i < 4, i++) {
arr[i] = function () { // 闭包函数
return i;
}
}
}
console.log(a()) // [4,4,4,4]
原因是闭包函数中的i变量访问的是包含函数a中的i,循环中i的指向都是同一个i变量,等a()执行结束,i变量的值是10,所以返回的是[4,4,4,4]
解决:
function a () {
var arr = [];
for (var i = 0,i < 4, i++) {
arr[i] = function (num) { // 闭包函数
return num;
}(i); // 通过传值,每次返回的num都会是i的循环值
}
}
闭包的应用:
上例是一种应用,另一种应用:特权方法,(只能通过闭包函数访问包含函数的变量和方法)。
function Creat(){
var arr = [];
this.arrs = function (name) {
arr.push(name);
console.log(arr)
}
}
var a = new Creat()
a.arrs('zhang'); // zhang
a.arrs('ss') ; // zhang ss
闭包的原理:
在后台执行环境中,闭包包含着它自己的作用域、包含函数作用域、全局作用域。通常函数作用域及其所有变量都会在函数执行完毕后销毁,但是当函数返回一个闭包,函数作用域将会存在于内存中至到闭包销毁为止
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署