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),函数也可以作为参数传递成函数变量.最近几年函数式也因为其无副作用的特性. ...
随机推荐
- pycharm通过unittest框架批量执行Python脚本用例
1.如下图点击进入配置页 2.新增一个配置,“2”标签选择要执行的脚本的目录或者脚本文件,“3”标签选择要执行的脚本的目录
- 题解【洛谷P2615】[NOIP2015]神奇的幻方
题目描述 幻方是一种很神奇的 \(N \times N\) 矩阵:它由数字 \(1,2,3,\cdots \cdots ,N \times N\) 构成,且每行.每列及两条对角线上的数字之和都相同. ...
- LED Magic Light - How Does The LED Light Change Color?
The LED Magic Light states that the color-changing LED is not an LED in the package, but three ...
- AJAX-状态属性
XMLHttpRequest对象的readyState属性 作用:表示xhr对象的请求状态 值:由0到4表示5个状态 0:请求尚未初始化 1:已经打开到WEB服务器的连接,正在向服务器发送请求 2:请 ...
- (c#)奇数值单元格的数量
题目 解
- pyodbc-的一些说明
cursor的description 可以获得一些关于表的信息 info=cursor.description 此时表中有多少列就有多少个元素,一个元素就是一列的信息(格式是tuple),所以这里的i ...
- 题解 UVA1335 【Beijing Guards】
UVA1335 Beijing Guards 双倍经验:P4409 [ZJOI2006]皇帝的烦恼 如果只是一条链,第一个护卫不与最后一个护卫相邻,那么直接贪心,找出最大的相邻数的和. 当变成环,贪心 ...
- 给大家推荐一些Java初学者所看的书籍
一.适合初学者的经典Java书籍; 比方说<Java核心技术卷>,<Effective Java中文版(第2版)> 二.Java开发者必读: <clean code> ...
- C++算法导论第九章O(n)期望选择序列第i小的数字
#include<iostream> #include<vector> #include<algorithm> #include<time.h> usi ...
- es6模块化设计
//导出 //方式一 export const name = 'hello' export let addr = 'chengdu' export var list = [1,2,3] //方式二 c ...