13-闭包

十三.闭包

闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。直观的说就是形成一个不销毁的栈环境。

先考虑一个问题

function foo(){
    var a = "我是foo里面的a";
}
foo();//这段代码执行之后,foo里面的a还存在嘛?

结果显而易见,a已经不存在了。因为foo执行完了之后foo的作用域消失了,所以作用域里面的变量不见了,被销毁了。

咱们需要用某种方法来获得foo里面的a,怎么办呢?简单

function foo(){
    var a = "我是foo里面的a";
    return a;//将变量a给return出来 
}
let b = foo();//此时b就获得foo里面的a了。

这里有一个概念需要大家理解:非对象数据类型都是非引用类型,那么b和a是什么关系。a是原始的值,b是a执行foo代码瞬间的值的拓印(副本)。也就是说如果我以某种方式修改了a的值,那么b的值没有任何改变。也谈不上使用foo的内部值了。其实此时foo内部的变量也被销毁了。

既然非对象不行,那么对象呢?

function foo(){
    var o = {
        "name":"GinTama"
    }
    setTimeout(function(){
        o.name = "我被改变了";
    },3000)
    return o;
}
var b = foo();//此时我们foo内部的对象o已经被外部引用了,修改o的值
//并且b.name会被改变

发现了没?foo作用域里面的变量o被外部引用了。但是作用域还是消失了,只有o被保留了下来。如何保留下来foo的作用域呢?内部函数能访问外部函数的作用域,于是

function foo(c){
    var num = c;
    return function A(){
        num++;
        return num;
    }
}
var b = foo(5);//b是什么?他保留了什么?
b();//6
b();//7

大家发现了没?保留下来了一个函数A,这个函数A可以访问foo的作用域里面的num并对他进行改变。这意味着num的作用域在foo执行完成之后保留下来了,保留在了函数A中。

上面就是一个简单的累加器

闭包:函数可以保留自己的作用域并可以访问它的作用域就产生了闭包。

闭包的影响: 会使得原有的作用域不消失,导致内存泄漏(可分配的内存的资源减少)。

闭包的作用

  • 封装,私有化属性
function create(){
    var pika = {
        "money": 100
    }
    console.log("你的钱是:"+pika.money)
    return {
        "add":function(){
            pika.money+=10;
            console.log("你的钱是:"+pika.money);
        },
        "lost":function(){
            Gin.money-=5;
            console.log("你的钱是:"+pika.money);
        },
        "get":function(){
            return pika.money;
        }
    }
}
var mint = create();//"你的钱是:100"
mint.add();//"你的钱是:110"
mint.lost();//"你的钱是:105"
var minter = create();
minter.get();//100

在这里pika这个对象完全变成了一个私有对象,里面的值已经无法直接获取,可以通过已经定义好的自定义的方法来访问它。

还有很多

比如:

function foo(){
    var ss = 123
    function A(){
        console.log(sss)
    }
    window.$ = A;//将foo作用域里面的A存储到全局window下的$中也是形成闭包。
}
foo();

直接绑定到全局中

还有最常见的循环绑定的问题:

function foo(){
    var arr = [];
    for(var i = 0;i<10;i++){
        arr[i]=function(){
            console.log(i)
        }
    }
    return arr
}
var mylist = foo()//mylist是一个存了10个函数的数组
//对数组每一个值执行的过程中就会出现意外情况,也可以用闭包来解决
function foo(){
    var arr = [];
    for(var i = 0;i < 10;i++){
        arr[i]=(function(j){
            return function(){
                console.log(j)
            }
        })(i)
    }
    return arr
}
var mylist = foo();//此时梳理出来mylist是一个数组,每个打印出来就是对应的i的值
function foo(){
    var arr = [1, 2, 3];
    for(var i = 0;i<10;i++){
        (function(j){arr[j]=function(){
            console.log(j)
        }})(i)
    }
    return arr
}
var mylist = foo()//mylist是一个存了10个函数的数组
//对数组每一个值执行的过程中就会出现意外情况,也可以用闭包来解决
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值