闭包与柯里化函数

闭包
作用域
要理解闭包,首先必须理解Javascript特殊的变量作用域。
变量的作用域无非就是两种:全局变量和局部变量。 Javascript语言的特殊之处,
就在于函数内部可以直接读取全局变量。我们有时候需要得到函数内的局部变量值。。
因此我们可以用函数套函数,并返回里面的函数来访问外层函数内部的变量,

什么是闭包
闭包是指有权访问另一个函数作用域中的变量的函数,
创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量
闭包的特点和优点
闭包的特点
1.函数嵌套函数
2.函数内部可以引用外部的参数和变量
3.参数和变量不会被垃圾回收机制回收
闭包的优点
1.希望一个变量长期驻扎在内存中
2.避免全局变量的污染
3.私有成员的存在

嵌套函数的闭包
定义的函数fun1,里面有一个sum,前面我们说过return是可以返回任何值得,
包括函数,因此在该案例中我们直接返回一个function函数,这样的写法等同于右图。同样嵌套执行以后,
因为fun1这个函数执行后保存为了变量fun2,也就是说fun2就是fun1内部那个匿名函数,
因此在执行fun2后就执行了一次fun1中的那个匿名函数,fun2是被保存到了外部变量,
所以函数运行完后sum并没有被清理掉,因为外面有对于这个匿名函数的引用,因此,再次执行时,sum被继续连加。
直到最后fun2被赋值为null的时候,fun1当中的匿名函数引用才被切断,这时候也把这个sum清理掉了。

  function fun1(){
        var sum=1;
        return function(){
            sum++;
            return sum;
        }
    }
    var fun2=fun1();
    console.log(fun2());//2
    console.log(fun2());//3

闭包内的作用域
fun1是作为一个自执行函数返回定义的,因此fun1实际上是返回的对象,而对象下有一个方法sum,
因此fun1.sum就是调用该对象下的sum方法,注意,a是自执行函数的
私有变量,b是对象的共有属性,因此,调用b的时候this.b可以在对象内调用,
也可以在外部使用this.b调用,但是在外部是无法调用变量a的,因为他是局部变量。

var fun1=(function(){
    var a=3;
    return {
        b:7,
        sum:function(){
        return this.b+a;
        }
    }
})()
console.log(fun1.sum());//10

柯里化函数
柯里化函数利用了闭包的特点,传入的参数会做存储留用,等到参数传完了,再对参数做处理。

案例一:点击文档中的六个按钮,当所有按钮都点击完之后弹出对话窗。
思路,给每个按钮增加index属性,每次点击执行函数all返回的函数,将每个按钮的index存储到对象中,
如果有就不存储,然后设置累加器,存储就累加,当累加到6即存储完毕,然后弹出对话窗。

var buttons=document.querySelectorAll("button")
for(var i=0;i<buttons.length;i++){
    buttons[i].addEventListener("click",clickHandle)
    buttons[i].index=i+1+""
}
var a = all()
function clickHandle(e){
    a(this.index)
}
function all(){
    var obj={}
    var counter=0
    return function(index){
        if(obj[index]) return
        obj[index] = index
        counter++
        console.log(obj,counter)
        if(counter===6){
            alert("实验成功")
            for(var key in obj){
                delete obj[key]
            }
            counter=0
        }
    }
}

案例二:
运行一个函数,如果传参,将参数存储,如果不传参,将存储的参数累加并打印。

function curry(fn) {
     var arg=[];
     return function () {
         if(arguments.length===0){
             fn.apply(null,arg);
         }else{
             var arr=Array.from(arguments);
             arg=arg.concat(arr);
         }
     }
 }
 function getSum() {
     var arr=Array.from(arguments);
     var sum=arr.reduce(function (sum,item) {
         return sum+item;
     });
     console.log(sum);
 }
var fn=curry(getSum);
 fn(10);
 fn(20);
 fn(30);
 fn();
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值