闭包基础

1.闭包的概念

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>闭包1</title>
</head>
<body>
<script>
/*
    闭包的概念:函数嵌套函数,内部函数可以引用外部函数的参数和变量,外部函数执行完了之后,其变量和参数也不会被垃圾回收机制收回
*/
function fn1(){


    var a=5;

    function fn2(){

        alert(a);
    }
    return fn2;
}

fn=fn1();//fn1执行完后,变量a并没有被垃圾回收机制收回
fn();//在这里,还可以访问到fn1中的变量a

</script>
</body>
</html>

2.闭包的作用和应用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>闭包2</title>
    <style type="text/css">

        li{background: #000;border:2px solid #fff;color: #fff;list-style: none;}

    </style>
</head>
<body>

    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
<script>
/*
    闭包的作用:

    1)让变量长期驻扎在内存当中
    2)避免全局变量的污染
    3)让函数拥有私有成员

    闭包的应用:

    1)模块化代码:模仿块级作用域

    2)在循环中直接找到对应元素的索引
*/



//避免全局变量的污染
/*
var a=1;
function fn1(){

    a++;
    alert(a);
}
fn1();//2
fn1();//3
alert(a);//3   全局变量被改变


function fn2(){

    var a=1;
    a++;
    alert(a);
}
fn2();//2
fn2();//2


//通过闭包实现每次调用a累加,同时又不会改变全局变量
function fn3(){

    var a=1;
    return function fn4(){

        a++;
        alert(a);
    }
}

fn=fn3();

fn();//2
fn();//3

//立即调用函数:模块化代码
fn=(function (){

    var a=1;
    return function fn5(){

        a++;
        alert(a);
    }
})();
fn();//2

*/


//让函数拥有私有成员
/*var fn1=(function (){

    var a=1;
    function fn2(){
        a++;
        alert(a)
    }
    function fn3(){
        a++;
        alert(a);
    }

    return{
        "fn2":fn2,
        "fn3":fn3
    }
})();

fn1.fn2();//2
fn1.fn3();//2

alert(a);//undefined
fn2();//undefined
fn3();//undefined*/



(function (){

    //块级作用域

    alert(1);

})();


//在循环中直接找到对应元素的索引

/*var aLi=document.getElementsByTagName('li');

//方法一
for (var i =0;i<aLi.length;i++) {

    (function (i){

        aLi[i].onclick=function (){


            alert(i);
        }
    })(i);
}

//方法二
for (var i =0;i<aLi.length;i++) {

        aLi[i].onclick=(function (i){


            return function (){

                alert(i);
            }

        })(i);
}
*/

</script>
</body>
</html>

3.闭包的注意事项

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>闭包2</title>
    <style type="text/css">

        li{background: #000;border:2px solid #fff;color: #fff;list-style: none;}

    </style>
</head>
<body>

    <div id="div1" style="background:#ff0">aaa</div>
<script>
/*
    闭包注意事项:

    IE8-下会引发内存泄漏:内存泄漏就是指浏览器不关闭,内存一直不会被释放

    在理解内存泄漏时,我们先来了解一下JS中的垃圾回收机制


    JS中的内存回收是自动回收的,主要有两种方式:

        1)标记清除

            变量进入环境(例如,在函数中声明一个变量),则将这个变量标记为'进入环境',当变量离开环境时,则将其标记为离开环境。垃圾收集器会自动回收那些离开环境的变量所占用的内存


        2)引用计数

            引用计数的含义是跟踪每一个值被引用的次数。当声明一个变量并将一个值赋给该变量
            ,则这个值的引用次数加1。如果这个变量又取了另外一个值,则这个值得引用次数减1,当这个值得引用次数变为0时,就可以将其占用的内存空间回收回来。


    内存泄漏就是由于引用计数方式中的循环引用造成的,在下面的例子中,oBjectA和objectB分别指向一个Object类型的对象,则这两个对象的引用计数都是1,然后oBjectA和objectB通过各自的属性互相引用,oBjectA和objectB指向的那两个对象的引用计数都变成了2,这样就造成内存无法回收。(这里希望大家搞清楚一个概念,oBjectA和objectB的值才是对象,oBjectA和objectB本身是变量)。现代浏览器都是采用标记清除的垃圾回收策略,但是在IE8-中的BOM和DOM并不是原生的JavaScript对象,其BOM和DOM使用c++以COM对象的形式实现的,而COM对象的垃圾回收机制采用的就是引用计数策略
*/

    function fn(){

        var objectA=new Object();

        var objectB=new Object();


        objectA.attr1=objectB;

        objectB.attr2=objectA;
    }
</script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值