JavaScript(五)闭包

12,闭包

函数作为返回值,在Java函数本质还是一个对象,因此可以把一个函数作为返回值

function f1() {
   return function (x) {
         return x*x;
   }
}
var res = f1();//调用f1获得一个代执行的函数
res(2);//4

闭包深入理解:在局部作用域中访问了其他局部变量

//循环返回函数值,注意引用的循环变量,会发生改变!!!!
//(js的变量提升)函数在调用时候访问的是一个全局作用域的i
function f() {
    var arr=[];
    for (var i = 0; i < 3 ; i++) {
         arr.push(function () {
              return i*i;
         })
    }
    return arr;
}
f[0]();//0
f[1]();//1
f[2]();//4
//闭包可以理解为一个闭包就是一个没有释放资源的栈区
// ,栈区内的变量处于激活状态。
// 上面的例子中for循环在执行时系统分配内存,js执行线程创建执行栈区,
// 执行时候检测到立即执行函数里的变量i被内部函数引用,所以该栈区在内存中没有被释放,
// 函数(数组元素)被调用时候根据作用链首先访问到的是上一级作用域(立即执行函数)的变量。

//解决方法1:通过构造一个立即执行的函数,数组中的每个函数有单独的作用域
//每个函数就处于一个立即执行函数的函数作用域中
function f5() {
    var arr=[];
    for (var i = 0; i < 3 ; i++) {
        arr.push(function (i) {
            //让f3函数的作用域限定在一个立即执行函数的函数作用域
            return function () {
                  return i*i;
            }
        }(i));
    }
    return arr;
}
var result=f5();
result[0]();//0
result[1]();//1
result[2]();//4


//解决方法2:这里我发现将var改为let,就没事了.ES6标准中,通过let构建块级作用域,解决问题
function f4() {
    var arr=[];
    for (let i = 0; i < 3 ; i++) {
        arr.push(function () {
            return i*i;
        })
    }
    return arr;
}
let f2 = f4();
f2[0]();//9
f2[1]();//9
f2[2]();//9
  • 利用闭包封装一个私用变量
function create_counter(initial) {
    var x = initial || 0;
    return {
        inc: function () {
            x += 1;
            return x;
        }
    }
}
var c1 = create_counter();
c1.inc(); // 1
c1.inc(); // 2
c1.inc(); // 3

var c2 = create_counter(10);
c2.inc(); // 11
c2.inc(); // 12
c2.inc(); // 13

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值