js闭包解析

引言:

javascript中有个很重要的概念,就是变量的作用域,js的变量无非两种-全局变量和局部变量,局部变量在函数内定义,函数外面是访问不到的,但是有时候我们要访问函数内部的变量,怎么办呢? 我们稍微变通一下,于是就有了闭包的概念;


闭包概念:

由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包理解成“定义在一个函数内部的函数”。简单理解就是在一个函数内定义了一个函数fn,然后在函数外去调用它,就产生了闭包;


闭包的作用:

在函数外面能访问函数内定义的局部变量;另一个就是让这些变量的值始终保持在内存中。

这种情况下,我们是不能访问到局部变量的

function f1(){
  var n=999;
}

alert(n); // error

如果我们要访问n就要使用闭包:

    function f1(){
        var n=999;
        function f2(){
            alert(n);
        }
        return f2;
    }
    var f3=f1();
    f3();//999

此时n的值是被保存在内存中,就是因为这点,闭包也是有缺点的,如果频繁使用闭包,就容易占用内存,解决的方法是退出函数之前,将不使用的局部变量全部删除。


如果函数内外定义了同一个变量会有冲突吗?

看一个面试常用的题目:

    var a=1;
    function f1(){
     var a =2;
     alert(a);  
    }       
    f1();
    alert(a);//结果是2,1

这是因为a使用了var关键字,维护a的作用域在函数内部,而不受外部定义的影响

再来看:

    function f1()
    {
      a =2;
     alert(a);  
    }   
    var a=1;    
    f1();
    alert(a);//结果是2,2

真是奇怪,两次都是2,在这里f1的a没有使用var,所以是全局变量,在外面定义了a=1后执行函数f1,a又被赋值为2,所以两次都alert 2;


闭包在返回数组中应用

举一个难一点的例子:

var arr = [1, 2, 3]; 
var square = function (x) { 
    return x * x; 
}; 
var funcs = makeClosures(arr, square); 
alert(funcs[1]());

这里要求弹出的数值是4

一般我们是这样写的

function makeClosures(arr, fn) {
    var result = new Array();
     for(var i=0;i<arr.length;i++){
        result[i] = function(){
            return fn(arr[i]);             
        };
    }
    return result;
}

一看没错呀,可是执行的时候会出现问题,弹出NaN,这是为什么,NaN其实表示不是数字的意思,上面这种写法会导致result的每个函数都是fn(arr[arr.length]),数组溢出,这是因为i随着循环结束值为2,然后执行完最后一次又加一等于3,那arr[3]自然是个undifind,所以弹出NaN,


还有for in写法,这种写法i最大为2,所以result的每个函数都是fn(arr[2]);

function makeClosures(arr, fn) {
    var result = new Array();
    for(i in arr){

        result[i] = function(){
            console.log(i);
            return fn(arr[i]);             
        };
    }
    return result;
}

使用闭包解决问题,

function makeClosures(arr, fn) {
     var result = [];

    for(var i=0; i<arr.length; i++){
        result[i]=function(num){
             return function(){
                 return fn(num);
             };
         }(arr[i]); 
    }
     return result;
 }

result[i]=function(num){}(arr[i]);这句代码意思是传入 arr[i]并且马上执行function,里面arr[i]就被正确的传入里面的num,保存在内存中,在里面返回一个匿名函数,就达到了我们要的效果


这里只对闭包概念做简单描述,和举几个简单的例子帮助理解闭包,其实闭包在实际项目中的运用要复杂得多,如果有更好的见解,欢迎讨论!

个人站 https://gdmec07140603.github.io/ 欢迎访问

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值