js笔记04-闭包:定义在一个函数内部的函数

函数作为返回值

普通的对数组的求和

function sum(arr) {
    return arr.reduce(function (x, y) {
        return x + y;
    });
}

sum([1, 2, 3, 4, 5]); // 15

如果先不求和,到后面使用到时,再求和,可以这样:

function lazy_sum(arr) {
    var sum = function () {
        return arr.reduce(function (x, y) {
            return x + y;
        });
    }
    return sum;
}

调用时

var f = lazy_sum([1, 2, 3, 4, 5]); // function sum() 将f赋值为lazy_sum函数
                                   //里面定义的一个函数名  sum

f();//15 真正调用f()时,才进行计算.

相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构

当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数

闭包

理解 返回的函数并没有立刻执行

function count() {
    var arr = [];
    for (var i=1; i<=3; i++) {
        arr.push(function () {
            return i * i;
        });
    }
    return arr;
}

var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];

// 调用f1(),f2()和f3()结果应该是1,4,9,但实际结果是:

f1(); // 16
f2(); // 16
f3(); // 16
//全部都是16
//因为函数不是立刻返回的,而且,返回的是 return i * i;
//返回时,i的值已经是4了,所以 答案就是16

返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
如果一定要用,就再引入函数,使其绑定当前循环变量的值,略过.

闭包不仅仅为了返回一个函数然后延迟执行
封装私有变量:

'use strict';

function create_counter(initial) {
    var x = initial || 0;
    return {
        inc: function () {
            x += 1;
            return x;
        }
    }
}

//这样用

var c1 = create_counter();
c1.inc(); // 1
c1.inc(); // 2
c1.inc(); // 3

var c2 = create_counter(10);
c2.inc(); // 11
c2.inc(); // 12
c2.inc(); // 13

在返回的对象中,实现了一个闭包,该闭包携带了局部变量x,并且,从外部代码根本无法访问到变量x。换句话说,闭包就是携带状态的函数,并且它的状态可以完全对外隐藏起来。

闭包创建新的函数pow2和pow3:

'use strict';

function make_pow(n) {
    return function (x) {
        return Math.pow(x, n);
    }
}

// 创建两个新函数:
var pow2 = make_pow(2);
var pow3 = make_pow(3);

console.log(pow2(5)); // 25
console.log(pow3(7)); // 343

你可能感兴趣的:(js笔记04-闭包:定义在一个函数内部的函数)