闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。

常见闭包出现的问题

function createFunction(){
            var result = new Array();
            for(var i=0; i<10; i++){
                result[i] = function(){
                    return i;
                }
            }
            console.log('i 的值:'+ i)
            return result;
        }

createFunction() 返回的结果

图片描述

当我们调用 createFunction()[1]();时返回的是

图片描述

事实上arr的每一项调用的结果都是10

为什么呢?

事实上你在调用每一项时,其实是这样的

function childFunction(){
           var i = 10;
            return function(){
                return i;
            }
        }

这个 i 来自它的父级作用域

或者我们这么说,return i; 中的 i 跟 for循环中的 i 其实是不一样的。因为此时的

图片描述

函数并没有调用,而当你调用的时候,它才去作用域链搜索 i 的值。而此时 i = 10;

我们尝试在返回之前更改 i =9999;

图片描述

得到证明。

那么要怎样才能让它返回我们预期的那样呢?
我们只要把 result [i] 中的 i 当做参数传进函数
图片描述

result[i] = (function(num){
            return function(){
                return num;
            }
        })(i)

这一段代码到底发生了什么?我们让 外层 的函数传入参数并立即执行,此时里面的 num 等于传入的参数, 等到最内层函数调用的时候,它会拿到外层的num。

最后,很多人以为闭包指的是一个函数被一个函数返回,其实不是。它指的是 有权访问另一个函数作用域中的变量的函数,跟是不是被 返不返回并没有关系。我们一般让其返回一个函数,是希望这个闭包能按照我们的预期进行。


Ryan
91 声望3 粉丝