function a() {
    var num = 100;
    function b() {
        num ++;
        console.log(num);
    }
    return b;
}

var demo = a();
demo();    // 101 aAO{ num: 101} 保存到了demo 执行完b被销毁
demo();    // 102 aAO{ num: 102} num读的是aAO里的

当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄露。

闭包的作用

  • 实现公有变量
//函数累加器
function add() {
    var count = 0;
    function demo(){
        count ++;
        console.log(count);
    }
    return count;
}
var counter = add();
counter(); // 1
counter(); // 2
counter(); // 3
  • 可以做缓存(存储结构)
// 公用一个testAO
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]();  // 101
myArr[1]();  // 100

 

  • //
    function eater() {
        var food = \'\';
        var obj = {
            eat:function () {
                console.log(\'i am eating \' + food);
                food = \'\';
            },
            push: function (myFood) {
                food = myFood;
            }
        }
        return obj;
    }
    
    var eater1 = eater();
    
    eater1.push(\'banana\');
    eater1.eat();
    可以实现封装,属性私有化

        Person()

  • 模块化开发,防止污染全局变量.

立即执行函数

针对初始化功能的函数

执行完就会立即释放

// 书写规范
// (function (){}()); // w3c建议
// (function (){})();


// 执行完 立即销毁  执行完就被释放
(function(){
    var a = 123;
    var b = 234;
    console.log(a + b);
}())

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

// 只有表达式才能被执行符号执行
// 函数声明
// function test(){}
// function test(){}() // 报错 函数声明不能直接执行
// 正确打开方式 test()

// 函数表达式
var test = function(){
    console.log(1);
}()  // 加() 立即执行

// 能被执行符号执行的表达式 名字自动被忽略
var test2 = function (){
    console.log(2);
}()
test2(); // undefined; 因为立即执行过了,所以不能使用

// + - ! 正 负 非 先要把后面转换为Number 后面有执行括号 所以先执行后转换 如果不加执行符号 函数不会执行 log 不会输出 但res结果还是为 NaN
var res = + function test(){
    console.log(3); // 不会报错 正常输出
}()

- function test(){
    console.log(4); // 不会报错 正常输出
}()

! function test(){
    console.log(5); // 不会报错 正常输出
}()

// && || / * 前面需要有个值 a结果为NaN
var a  = 1 * function(){
    console.log(\'11\');
}()

// 不会报错 不会输出
function demo(a,b,c,d) {
    console.log(a + b + c + d);
}(1,2,3,4) 
// 运行时 为了不报错 系统当做逗号操作符
// 解析为
//function demo(a,b,c,d) {
//    console.log(a + b + c + d);
//}
//(1,2,3,4)

// demo // 输出 function demo(a,b,c,d) { console.log(a + b + c + d)};

 

收藏 打印