JS闭包

来源:互联网 发布:中国dna数据库 编辑:程序博客网 时间:2024/05/11 04:51

1.前言引出:变量分为全局变量和局部变量,在函数内部可以直接读取全局变量。那么,在函数外部如何读取函数内部的局部变量呢? 正常情况下是不可以的,但采用闭包可以解决函数外部读取函数内部的局部变量。
2.闭包实例:

function a () {    var n = 10;    function b() {        alert(n);    }    return b;}var c = a();

讲解:闭包就是在函数a内部定义一个内部函数b,根据执行环境和变量作用域链可知,函数b是可以访问函数a中的变量的,然后将函数b返回(注意:此时是函数b的引用)。那么通过var c = a(); 变量c就拿到了函数b的引用,而函数b是可以访问函数a中的局部变量,那么c就间接访问到了a中的局部变量。从而解决了在函数a外部访问函数a中的局部变量的问题。此外,根据垃圾回收机制可知,若是函数执行完后,函数内的局部变量会立刻销毁,但是,由于c引用了函数b,而函数b引用了函数a内的局部变量,故垃圾回收器不会回收函数a,b中的变量,故这些变量始终保持在内存中。
闭包的作用的是:
(1)在函数外部可以读取函数内部的变量;(2)这些变量的值始终保持在内存中
3.证明函数的变量始终保持在内存中:

function a() {    var n = 1;    function b() {        n++;        alert(n);    }    return b;}var c1 = a();c1(); // 2c1(); // 3var c2 = a();c2(); // 2c2(); // 3

4.闭包只能取得包含函数中任何变量的最后一个值,例子如下:

function createFuntions() {    var result = new Array();    for (var i = 0; i < 10; i++) {        result[i] = function() {            alert(i);            return i;        };    }    return result;}var c = createFuntions();for (var i = 0; i < c.length; i++) {    c[i](); // 结果为 10,10,10,....}

原因:for循环执行完了之后,i的值变成10了,存在内存里边,因为闭包的原因,i一直在内存中,不会被销毁,并且值是10
解决方法:

function createFuntions() {    var result = new Array();    for (var i = 0; i < 10; i++) {        result[i] = function(num) {            //alert(num);            return num;        }(i);    }    return result;}var c = createFuntions();for (var i = 0; i < c.length; i++) {    console.log("i:",c[i]());}

此时,会报错:TypeError: Property ‘0’ of object [object Array] is not a function,原因:
立即执行的函数不是这样写的(立即执行函数(),返回的是函数执行的结果) 你这里返回的是一个num,不是一个函数 这里又用小括号去执行c[i],c[i]是那个num,不是函数,咋执行呢
改进:
改进一:

function createFuntions() {    var result = new Array();    for (var i = 0; i < 10; i++) {        result[i] = function(num) {            //alert(num);            return num;        }(i);    }    return result;}var c = createFuntions();for (var i = 0; i < c.length; i++) {    console.log("i:",c[i]);}

改进二(利用闭包):

function createFuntions() {    var result = new Array();    for (var i = 0; i < 10; i++) {        result[i] = function(num) {            //alert(num);            return function() {                return num;            };        }(i);    }    return result;}var c = createFuntions();for (var i = 0; i < c.length; i++) {    console.log("i:",c[i]());}

改进一或者改进二均可以

0 0
原创粉丝点击