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),函数也可以作为参数传递成函数变量.最近几年函数式也因为其无副作用的特性. ...
随机推荐
- 大数据-hdfs技术
hadoop 理论基础:GFS----HDFS:MapReduce---MapReduce:BigTable----HBase 项目网址:http://hadoop.apache.org/ 下载路径: ...
- JSP中四大作用域详解
四大作用域 为了在页面.请求.和用户之间传递和共享数据,JSP提供了四个不同的作用域:page(页面作用域).request(请求作用域).session(会话作用域).application(应用程 ...
- centos长ping输出日志的脚本
为监控某服务器的网络情况,制作一个sh脚本,记录ping的长过程,并输出日志以备观察. 1.脚本如下 cat /home/summer/ping100.sh #!/bin/sh ping 172.16 ...
- C++转换构造函数和隐式转换函数
今天是第一次听到C++还有个转换构造函数,之前经常见到默认构造函数.拷贝构造函数.析构函数,但是从没听说过转换构造函数,隐式转换函数也是一样,C++的确是够博大精深的,再次叹服! 其 ...
- 第二十五篇 玩转数据结构——链表(Linked List)
1.. 链表的重要性 我们之前实现的动态数组.栈.队列,底层都是依托静态数组,靠resize来解决固定容量的问题,而"链表"则是一种真正的动态数据结构,不需要处理固定容 ...
- opencv:图像去噪(椒盐噪声)
#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...
- kali 安装与配置
打开虚拟机 新建一个虚拟机 导入虚拟文件 然后进行下面的步骤 开启虚拟机 语言:中文简体 地区: 中国 语言: 汉语 自动安装 配置网络 配置域名 填写密码(两次一致) 自动校对时钟 使用整个磁盘 选 ...
- MVVM架构的理解
摘自维基百科 MVVM(Model–view–viewmodel)是一种软件架构模式. MVVM有助于将图形用户界面的开发与业务逻辑或后端逻辑(数据模型)的开发分离开来,这是通过置标语言或GUI代码实 ...
- Sublime Text3搭建完美开发环境(Python+PHP+Javascript+nodejs+C++)
一.Sublime配置(如已安装Package Control可跳过) sublime下载地址:http://www.sublimetext.com/3 安装Package Control插件: 直接 ...
- 解密国内BAT等大厂前端技术体系-美团点评之下篇(长文建议收藏)
引言 在上篇中,我已经介绍了美团点评的业务情况.大前端的技术体系,其中大前端的技术全景图如下: 上篇重点介绍了工程化和代码质量的部分,工程化涵盖了客户端持续集成平台-MCI.全端监控平台-CAT.移动 ...