JavaScript学习笔记十四:闭包

来源:互联网 发布:超级列表框读取数据库 编辑:程序博客网 时间:2024/06/05 06:33

JavaScript教程传送门

函数作为返回值

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。例如:一个返回求和函数的函数

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(); // 15

闭包

当A函数的返回值是B函数时,A内部的局部变量还会被B函数引用,这里面会出现一个问题:

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(); // 16f2(); // 16f3(); // 16

全部都是16!原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了4,因此最终结果为16

返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

如果一定要引用循环变量,必须再创建一个函数,用该函数的参数绑定循环变量当前的值:

function count() {    var arr = [];    for (var i=1; i<=3; i++) {        arr.push((function (n) {            return function () {                return n * n;            }        })(i));    }    return arr;}var results = count();var f1 = results[0];var f2 = results[1];var f3 = results[2];f1(); // 1f2(); // 4f3(); // 9

闭包的使用场景

闭包可以作为一个携带状态的函数,并且它的状态可以完全对外隐藏起来:

'use strict';function create_counter(initial) {    var x = initial || 0;    return {        inc: function () {            x += 1;            return x;        }    }}var c1 = create_counter();c1.inc(); // 1c1.inc(); // 2c1.inc(); // 3var c2 = create_counter(10);c2.inc(); // 11c2.inc(); // 12c2.inc(); // 13

闭包还可以把多参数的函数变成单参数的函数。例如,要计算xy可以用Math.pow(x, y)函数,不过考虑到经常计算x2或x3,我们可以利用闭包创建新的函数pow2pow3

function make_pow(n) {    return function (x) {        return Math.pow(x, n);    }}// 创建两个新函数:var pow2 = make_pow(2);var pow3 = make_pow(3);pow2(5); // 25pow3(7); // 343
0 0
原创粉丝点击