理解闭包(二)

闭包只能取得包含函数中任何变量的最后一个值,这是作用域链的配置机制产生的副作用。下面的例子可以很清晰地说明这个问题。

 function foo() {
            var result = [];
            for( var i = 0; i < 10; i++){
                result[i] = function () {
                    return i;
                }
            }
            return result;
        }
        var it = foo();
        for( var j = 0; j < it.length; j++){
            console.log(it[j]());
        }

这个函数会返回一个数组,表面上看,数组里的每个函数会返回自己的索引值。但实际上,每个函数都会返回“10”。

由于闭包机制,返回的数组里每个函数都可以访问并返回i的值。但是,每个函数引用的是同一个变量i。当函数foo()执行后,此时i的值为10(注意,for循环的最后一次,i的值为9,但是i仍进行了自加运算值为10),所以数组里的每个函数返回的值为10。

但是我们可以通过创建另一个匿名函数强制让闭包行为符合预期,如下:

function foo1() {
            var result = [];
            for( var i = 0; i < 10; i++){
                result[i] = function (num) {
                    return function () {
                        return num;
                    }
                }(i);
            }
            return result;
        }

在重写foo1()函数后,每个函数就可以返回自己的索引值了。我们定义一个带有形参的匿名函数,立即执行并返回形参的值。我们将i传入匿名函数,由于函数参数是按值传递的,所以执行后返回i的当前值。因此foo1()返回的数组里面,每个函数会返回不同的数值。

实例源自《JavaScript高级程序设计》(第3版)

闭包是编程语言中一个重要的概念,特别是在函数式编程中常常会遇到。理解闭包可从以下几个方面入手: - **定义**:闭包是一种函数,它引用了在其定义范围之外的自由变量(非全局变量),并且这些引用的变量在函数被调用时仍然保持活跃状态。例如在 JavaScript 中,`function f1(){ var n = 1; function f2(){ alert(n); } return f2; } var f=f1(); f();` 这里的 `f2` 函数就是一个闭包,它引用了 `f1` 函数内部的变量 `n`,即使 `f1` 函数执行完毕,`n` 依然保持活跃状态,`f2` 函数依然可以访问 `n` [^2][^3]。 - **构成**:闭包通常由两部分组成,即内部函数(函数内嵌套定义的函数)和与其相关的环境(包含了自由变量的作用域)。在上述 JavaScript 例子中,`f2` 是内部函数,`f1` 的作用域是相关环境 [^3]。 - **特点**:内部函数可以访问外部函数的变量,即使外部函数已经执行完毕。闭包允许将函数与其相关的环境捆绑在一起,形成一个整体单元,以便稍后被调用。以 Python 代码 `def outer_function(x): def inner_function(y): return x + y return inner_function add_five = outer_function(5); result = add_five(3); print(result)` 为例,`inner_function` 作为闭包,在 `outer_function` 执行完毕后,依然可以访问 `outer_function` 传入的参数 `x` [^3]。 - **应用场景**:闭包在不同编程语言中有多种应用场景。在 Python 中,常用于实现装饰器、回调函数、工厂函数等功能;在 JavaScript 中,可用于设计私有的方法和变量,还可以利用闭包模拟私有属性,实现数据隐藏和封装,比如防抖和节流函数封装就使用了闭包 [^3][^4][^5]。 ### 代码示例 以下是 JavaScript 和 Python 中闭包的代码示例: ```javascript // JavaScript 闭包示例 function outer() { let count = 0; function inner() { return ++count; } return inner; } const counter = outer(); console.log(counter()); // 输出 1 console.log(counter()); // 输出 2 ``` ```python # Python 闭包示例 def outer_function(x): def inner_function(y): return x + y return inner_function add_five = outer_function(5) result = add_five(3) print(result) # 输出 8 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值