JavaScript 闭包&基于闭包实现柯里化curry和bind
闭包:
- 1 函数内声明了一个函数,并且将这个函数内部的函数返回到全局
- 2 将这个返回到全局的函数内中的函数存储到全局变量中
- 3 内部的函数调用了外部函数中的局部变量
闭包简述:
- 有权访问另一个函数局部作用域中的变量的函数
闭包清除:
- 将存储该内部函数的全局变量赋值为null,此时内部函数没有被引用,被垃圾回收机制回收
- 由此也可以得出,闭包形成的原因------ 基于引用计数与标记清除的JavaScript垃圾回收机制
优点:
- 有私有变量存在
- 避免全局污染
- 防止私有变量被垃圾回收
缺点:
- 势必造成内存泄漏
示例:
function fn1() {
var a = 1;
function fn2(){
var b = 0;
a ++;
b++;
console.log(a,b);
}
return fn2;
}
var fns = fn1();
fns();
fns();//3,1
//第二次执行fns,fns又创建新的执行期上下文,此间b经历了残忍地再初始化和重建
//而a因为在fn2的局外,又为全局变量fns所庇佑,于是得以苟且偷生,并继续接下来的运算
function fn1(s){ var a = 1; var o = {a:1}; return function(){ a++; o.a++; console.log(a,o.a); } } var fn = fn1(); fn(); fn(); fn(); fn();//5,5 fn = null;//清除闭包
运用:
- curring
- bind
curring :
1 函数多行执行
/** 闭包实现柯里化 柯里化主要做两件事情: 1 执行函数参数个数不为0时, 将参数列表用concat连接存储在数组arr中 2 否则执行参数列表为arr的执行函数 步骤: 1 在外部函数新建一个数组arr 2 当参数个数不为0时, arr在内部函数存储每次函数执行的参数列表, 返回并用全局变量接收内部函数, 形成闭包 3 当前执行函数的参数个数不为0时, 将参数列表存进数组 4 当执行函数的参数个数为0时, 执行参数列表为arr的执行函数 */ const add = (...args) => args.reduce((a, b) => a + b) const curry = function (fn) { const args = [] function temp(...newArgs) { if (newArgs.length) { args.push(...newArgs) return temp } return fn.apply(this, args) } temp.toString = function () { // console.log(add.apply(null, args)); return add.apply(null, args); } return temp } console.log(curry(add)(1)(2, 3)()); console.log('%s', curry(add)(2)(2, 3));
bind:
/* 实现bind: 将函数中的this指向绑定到bind函数的参数中 用apply实现 */ function bind(fn, obj) { return function () { //这里的传参要看是谁调用 console.log(arguments);//3,5,这里的参数是setTimeout传进来的 fn.apply(obj, arguments); } } function abc(_a, _b) { this.a = _a; this.b = _b; } var obj = {}; setTimeout(bind(abc, obj), 200, 3, 5);//执行function(){abc(3,5)}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
2019-02-19 MyBatis配置文件SqlMapCofing.xml(属性加载&类型别名配置&映射文件加载)
2019-02-19 Mybatis架构&MybatisDao的两种开发方式(原始Dao,接口动态代理)