作用域、作用域链、立即执行函数、闭包

闭包的作用:


1、实现公有变量

  eg:函数累加器

2、可以做缓存(存储结构)

  eg:eater

3、可以实现封装,属性私有化

  eg:Person();

4、模块化开发,防止污染全局变量

立即执行函数

//立即执行函数

//针对初始化功能的函数

//执行完之后就会被销毁,只能执行一次

1 var num = (function(a,b,c){
2     var d = a+b+c*2 -2;4     return d;5 }(1,2,3))

//只有表达式才能被执行符号执行,

//函数被括号包裹就变成了表达式

//函数声明不能被执行

可以用+ 、-将其转化为表达式

1 + function test(){
2     console.log();
3 }();
4 - function test(){
5     console.log();
6 }();

arguments

arguments是类数组对象,不能使用push方法;

1、实现公有变量

累加器

function add(){
    var num = 0;
    function a(){
    console.log(++num);
    }
return a;
}
var myAdd = add();
myAdd();
myAdd();
function add(){
            var count = 0;
            function demo(){
                count++;
                console.log(count);
            }
            return demo;
        }
        var counter = add();
        counter();//没调用一次累加一次
        counter();
        counter();
        counter();

解决闭包问题的方法:用立即执行函数

遍历元素加上事件,最好在循环中用立即执行函数,避免闭包问题;

arguments[0]和第一位参数之间的关系:同形连体,一个改变,另一个也随之改变,但不是同一个人;

 2、可以做缓存(存储结构)

        function test() {
            var num = 100;
            function a() {
                num++;
                console.log(num);
            }
            function b() {
                num--;
                console.log(num);
            }
            return [a,b];
        }
        var myArr = test();
        myArr[0]();
        myArr[1]();
        /* 
            a 运行后的 testAO, 与 a doing 里面的 testAO 一模一样
            a 和 b 连线的都是 test 环境,对应的一个闭包
            function a 和 function b 是并列的,不过因为 function a 在前,所以先执行 num ++,在
            执行 num --
            myArr[0]是数组第一位的意思,即 a,myArr[0]();就是执行函数 a 的意思;
            myArr[1]是数组第二位的意思,即 b,myArr[1](); 就是执行函数 b 的意思
        */

3、可以实现封装,属性私有化

        // 闭包的私有化变量问题
        function Deng(name,wife) {
            var prepareWife = "xiaozhang";//私有只有自己可以访问

            this.name = name;
            this.wife = wife;
            this.divorce = function (){
                this.wife = prepareWife;//私有变量不用加this访问
            }
            this.changePrepareWife = function(target){
                prepareWife = target;
            }
            this.sayPraprewife = function(){
                console.log(prepareWife);
            }
        }
        var deng = new Deng('deng','xiaoliu');

4、模块化开发,防止污染全局变量

        var name = 'bcd';
        var init = (function(){
            var name = 'abc';//这个name和外面的name不冲突
            function callName(){
                console.log(name);
            }
            return function(){
                callName(); //这个函数在外面使用时,自带上下文,不污染全局变量
            }
        }())
        init();
原文地址:https://www.cnblogs.com/zhizhi0810/p/10573793.html