JavaScript深入理解之闭包

JavaScript深入理解之闭包

* 关于闭包有不同的的定义,主要有以下三种,这三种定义的含义差不多*

  • 闭包是一个函数外加上该函数所创建时多建立的作用域
  • 闭包是指有权访问另一个函数作用域中变量的函数
  • 闭包是实现外部作用域访问内部作用域中变量的方法

* 闭包作用 *

  • 闭包用来突破作用域链

* 创建闭包方式 *

  • 创建闭包的常见方式是在一个函数内创建另一个函数

* 闭包主要有四种情况 *

情况一
function AA(propertyName) {
    return function() {
        var kk = propertyName;
        return kk;
    }
}

var aa = AA();
aa(123);        // => 123

* 上例中:内部返回函数能够获取propertyName,因为内部返回函数的作用域链中包括了AA的作作用域 *

情况二
var a = 'global';
var F = function() {
    var b = 'local';
    var N = function() {
        var c = 'inner';
        return b;
    }
    return N;
}

var inner = F();
console.log(inner());   // => 'local'
console.log(b);         // =>  b is not defined

* 上例中: a为全局变量,b和N为全局变量下一级目录,且b对N是可见的,a对b和N都可见,inner为全局变量,b和N对inner来说是不可见的,但是最后inner是获取到了b得值,怎么获取到的呢,就是通过闭包,此时的N就是一个闭包,将F的返回值赋值给了一个全局变量inner,因此inner可以访问F的私有空间。 *

情况三
var inner;
var F = function() {
    var b = 'local';
    var N = function() {
        return b;
    }
    inner = N;
}

F();        // 要先运行F,否则inner为undefined,因为inner没有值
console.log(inner());   // => 'local'

* 上例中:inner为全局变量,b和N为全局变量下一级,b和N对inner来说是不可见的,即inner不是不能访问到b和N的,但是最后inner得到了b的值,为什么呢,因为在F中定义了一个新的函数N,并将N赋值给了全局变量inner,因此N升级为全局变量,N既可以访问F的私有变量,又可以访问全局变量,赋值后的inner就是一个闭包 *

情况四: 循环中的闭包
var arr = [];

function F(){
    var i;
    for(i = 0; i < 3; i++){
        arr[i] = function() {
            return i;
        }
    }
    return arr;
}

F();
console.log(arr[0]());  // => 3
console.log(arr[1]());  // => 3
console.log(arr[2]());  // => 3

/*
执行完F()后,arr为:
arr = [
    function() { return 3 },
    function() { return 3 },
    function() { return 3 }
]
 */

* 上例中:我们创建了三个闭包,它们都指向了一个共同的局部变量i,但是,闭包不会记录它们的值,记录是的对它们的引用,当F执行完之后i的值为3,当闭包函数arr[i]去寻找i时,会沿着作用域链向上逐级寻找距离最近的i,又由于循环结束后i为3,因此三个闭包函数记录的都是对同一个i的引用,都指向数字3,解决这种情况可以使用立即执行函数或者通过一个中间变量来传递i(ps:作用域链本质上是一个指向变量对象的指针列表,它只引用但不实际包含变量对象) *

关于闭包注意点
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值