JavaScript 闭包&基于闭包实现柯里化和bind
闭包:
- 1 函数内声明了一个函数,并且将这个函数内部的函数返回到全局
- 2 将这个返回到全局的函数内中的函数存储到全局变量中
- 3 内部的函数调用了外部函数中的局部变量
闭包简述:
- 有权访问另一个函数局部作用域中的变量的函数
闭包清除:
- 将存储该内部函数的全局变量赋值为null,此时内部函数没有被引用,被垃圾回收机制回收
优点:
- 有私有变量存在
- 避免全局污染
- 防止私有变量被垃圾回收
缺点:
- 势必造成内存泄漏
示例:
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的执行函数
*/
function currying(fn) {
var arr = [];
return function () {
if (arguments.length > 0) {
// Array.from(arguments).forEach(item => arr.push(item));
//闭包,return的内部函数保有了外部函数变量
arr = arr.concat.apply(arr, arguments);
return;
}
return fn.apply(null,arr);//执行参数列表为arr的getSum函数
}
} function getSum() {
//执行的时候,将参数列表的参数归并求和
return Array.from(arguments).reduce(function (value, item) {
return value + item
});
}
//闭包,将返回的内部函数存储到全局变量
var fns = currying(getSum);
fns(1, 3, 5);
fns(2, 3, 5);
var sum = fns();
console.log(sum);
2 函数单行执行
function currying(fn) {
var arr = [];
return function () {
if (arguments.length > 0) {
arr = Array.from(arguments).concat.apply(arr, arguments);
return arguments.callee;//因为是单行执行,执行完一次需要返回此函数去执行下个参数列表
}
//参数列表为0,执行函数
return fn.apply(null, arr);
}
} function getSum() {
return Array.from(arguments).reduce((value, item) => {
return value + item;
});
} var fns = currying(getSum);
var sum = fns(1,1,1)(1,1,1)();
console.log(sum);
执行结果:
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)}
JavaScript 闭包&基于闭包实现柯里化和bind的更多相关文章
- 浅析 JavaScript 中的 函数 currying 柯里化
原文:浅析 JavaScript 中的 函数 currying 柯里化 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字 ...
- swift 学习(二)基础知识 (函数,闭包,ARC,柯里化,反射)
函数 func x(a:Int, b:Int) {} func x(a:Int, b:Int) -> Void {} func x(a:Int, b:Int) ->(Int,Int ...
- Scala 基础(十二):Scala 函数式编程(四)高级(二)参数(类型)推断、闭包(closure)、函数柯里化(curry)、控制抽象
1 参数(类型)推断 参数推断省去类型信息(在某些情况下[需要有应用场景],参数类型是可以推断出来的,如list=(1,2,3) list.map() map中函数参数类型是可以推断的),同时也可以 ...
- 温故而知新:柯里化 与 bind() 的认知
什么是柯里化?科里化是把一个多参数函数转化为一个嵌套的一元函数的过程.(简单的说就是将函数的参数,变为多次入参) const curry = (fn, ...args) => fn.length ...
- 一道javascript面试题(闭包与函数柯里化)
要求写一个函数add(),分别实现能如下效果: (1)console.log(add(1)(2)(3)(4)()); (2)console.log(add(1,2)(3,4)()); (3)conso ...
- JavaScript 反柯里化
浅析 JavaScript 中的 函数 uncurrying 反柯里化 柯里化 柯里化又称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间 ...
- 浅析 JavaScript 中的 函数 uncurrying 反柯里化
柯里化 柯里化又称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果. 因此柯里化的过程是 ...
- JavaScript中的反柯里化
转载自:https://www.cnblogs.com/zztt/p/4152147.html 柯里化 柯里化又称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函 ...
- JavaScript函数柯里化
函数式 JavaScript是以函数为一等公民的函数式语言.函数在JavaScript中也是一个对象(继承制Function),函数也可以作为参数传递成函数变量.最近几年函数式也因为其无副作用的特性. ...
随机推荐
- 一些关于网页标题的动态js特效
1.当转换页面时,标题改变 <script> document.addEventListener('visibilitychange',function(){ if(document.vi ...
- nmon help文档zh-han
nmon版本16g的提示 完整的帮助信息:nmon -h 屏幕统计:nmon 数据收集:nmon -f [-s <秒>] [-c <计数>] [-t | -T] 容量计划:nm ...
- python接口自动化测试 - requests库的post请求进行文件下载
前言 之前讲了文件上传,当然就有文件下载啦 文件下载操作步骤 极其简单,将二进制格式的响应内容存进本地文件中,根据需要下载的文件的格式来写文件名即可 down_url = 'https://www.i ...
- 如何处理python异常
1.python异常有那些? window的机器如果安装了python,则直接可以在idle中查看,打开idle,按F1即可打开帮助文档,按如下路径即可查看,也可以去python官网查看这里不说明了百 ...
- Abp.core中在应用层获取HttpContext对象
实际IHttpContextAccessor对象已经在底层实现了自动的依赖注入,只需要在应用层引入Microsoft.AspNetCore.Http,然后在构造函数中依赖注入即可. /// <s ...
- eclipse从svn导入静态文件
1.从eclipse 选择 导入 2.选择仓库和项目,选择finish 3.选择project项目导出
- Android App测试计划和设计测试矩阵
Android APP :日程管理APP 测试计划(Test Plan): 编号 测试时间 测试类型 测试计划 1. 5.1~5.5 单元测试 单元测试是由程序员自己来完成,程序员有责任编写功能代码, ...
- Docker - CentOS 7 安装
1. 概述 安装 docker markdown 显示有点问题 代码块里的 后面应该跟一个换行, 但是没有跟 这样会导致部分命令直接执行没有反应 2. 环境 os CentOS7 用户 root 3 ...
- BFSDFS模板
BFS模板: private static void bfs(HashMap<Character, LinkedList<Character>> graph,HashMap&l ...
- Bug搬运工-CSCvi02106 :Cisco 2800, 3800, 1560 APs: when connected to a Cisco Switch CDP-4-DUPLEX_MISMATCH log is seen
Cisco 2800, 3800, 1560 APs: when connected to a Cisco Switch CDP-4-DUPLEX_MISMATCH log is seen CSCvi ...