《javascript面向对象编程指南》——闭包
闭包:有权访问另一个函数作用域中的变量的函数,这样的话每个函数都可以被认为是一个闭包。但是大多数时候,该作用域在函数体执行完之后就自行销毁了
如果一个函数会在其父级函数返回之后留住对父级作用域链的话,相关闭包就会创建
首先是一个一般函数
var a = "global variable";
var F = function() {
var b = "local variable";
var N = function() {
var c = "inner local";
};
};
从全局到最里面的作用域链依次是:
- a、F()
- b、N()
- c
现在将N的空间扩展到F以外,并止步于全局空间以内,就产生闭包
var a = "global variable";
var F = function() {
var b = "local variable";
var N = function() {
var c = "inner local";
return b;
};
return N;
};
var inner = F();
inner(); //"local variable"
如上,只需在F空间return出N空间,然后将F()的调用赋值给全局变量inner,此时inner就是N函数,调用一下inner(),就相当于执行N(),但是这里N(),既可以访问其原有的作用域,也是全局函数
上述步骤就是突破作用域链
下面这种闭包,不是F()返回函数,而是直接在函数体内N赋值给全局变量inner
var inner;
var F = function() {
var b = "local variable";
var N = function() {
return b;
};
inner = N;
};
F(); //需要调用,才能将N赋值给inner
inner(); //"local variable"
相关定义与闭包
如果一个函数会在其父级函数返回之后留住对父级作用域链的话,相关闭包就会创建
function F(param) {
var N = function() {
return param;
};
param++;
return N;
}
var inner = F(123);
inner(); //124
如上,当返回的函数被调用时,param++已经执行过一次递增操作了,所以inner()返回的是被更新后的值
由此,函数所绑定的是作用域本身,而不是在函数定义时该作用域中的变量或变量当前返回的值
循环中的闭包
如下,是一个三次循环操作,每次迭代中都会创建一个返回当前循环序号的新函数
function F() {
var arr = [],
i;
for (i = 0; i < 3; i++) {
arr[i] = function() {
return i;
};
}
return arr;
}
var newArr = F();
console.log(newArr[0]()); //3
console.log(newArr[1]()); //3
console.log(newArr[2]()); //3
如上,结果都是3
我们在这里创建了三个闭包,而他们都指向了一个共同的局部变量i。但是,如上节所说,闭包并不会记录他们的值,他们所拥有的只是相关域在创建时的一个连接(引用)
当循环结束时i的值为3,所以这三个函数都指向这一个共同值(注意不是2)
解决1
function F() {
var arr = [],
i;
for (i = 0; i < 3; i++) {
arr[i] = (function(x) {
return function() {
return x;
};
})(i);
}
return arr;
}
var newArr = F();
console.log(newArr[0]());
console.log(newArr[1]());
console.log(newArr[2]());
如上,将i传递给另一个即时函数
解决2
function F() {
function binder(x) {
return function() {
return x;
};
}
var arr = [],
i;
for (i = 0; i < 3; i++) {
arr[i] = binder(i);
}
return arr;
}
var newArr = F();
console.log(newArr[0]());
console.log(newArr[1]());
console.log(newArr[2]());
如上,定义一个内部函数,将i本地化
分类:
javascript笔记
标签:
闭包
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 聊一聊 操作系统蓝屏 c0000102 的故障分析
· SQL Server 内存占用高分析
· .NET Core GC计划阶段(plan_phase)底层原理浅谈
· 盘点!HelloGitHub 年度热门开源项目
· 某Websocket反爬逆向分析+请求加解密+还原html
· DeepSeek V3 两周使用总结
· 02现代计算机视觉入门之:什么是视频
· 回顾我的软件开发经历:我与代码生成器的涅槃之路