码迷,mamicode.com
首页 > Web开发 > 详细

js 闭包

时间:2018-03-22 10:53:16      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:操作   cti   log   个人   例子   概念   函数参数   返回   i++   

重新刷jsES5基础知识,看到了闭包这块。遵循着又笨又懒的原则,我不想记录概念,就想知道它是怎么来的,先看个例子(廖雪峰官网闭包中的例子)。

说下想干什么,我想输出的results=[1,4,9]

function count() {
    var arr = [];
    for (var i=1; i<=3; i++) {
        arr.push(function () {
            return i * i;
        });
    }
    return arr;
}

var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
console.log(f1());
console.log(f2());
console.log(f3());

不好意思,js给了我一巴掌,这样输出的结果是16,16,16。出现了问题就要思考 为什么不是1,4,9而是16,16,16呢?我粗鲁的解释下:

1.我想要的运行顺序:

  第一步:开始循环跑起来,没毛病。

  第二步:变量i来了,给i一个值1,开始计算 1*1=1

  第三步:变量i来了,给i一个值2,开始计算 2*2=4

  第四步:变量i来了,给i一个值3,开始计算 3*3=9

  第五步:循环结束,i=4,我管i现在是啥,我车上的货都弄好了,打包装车[1,4,9]

  第六步:拉走

2.实际的运行顺序:

  第一步:开始循环跑起来,没毛病。

 

  第二步:变量i来了,开始计算 i*i=i的平方

 

  第三步:变量i来了,开始计算 i*i=i的平方

 

  第四步:变量i来了,,开始计算i*i=i的平方

 

  第五步:循环结束,i=4,我现在车的上的货是[i*i,i*i,i*i],还不能走,重新整理[4*4,4*4,4*4]

  第六步:拉走

重点是:我想先给i赋值,循环结束再装箱,实际是把i装箱,循环结束再赋值了。

大家时间都比较紧,所以请大声朗读这样出现错误的原因三遍:被return出来的东西引用会发生变化的变量(例子中的循环变量)

好的,问题已经出现了,如果我就是需要引用发生变化的变量呢。要解决问题就是闭包这个哥们了。

 

function count() {
    var arr = [];
    for (var i=1; i<=3; i++) {
        arr.push((function (n) {
            return function () {
                return n * n;
            }
        })(i));
    }
    return arr;
}

var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];

f1(); // 1
f2(); // 4
f3(); // 9

 

这里面用的到了IIFE(即时执行),请先运用你的大脑记录下他的结构,坐稳了,也就是我们写的那个函数里面的n等于i,原理就是函数的参数n绑定循环变量i,无论i后续如何更改,已绑定到函数参数的值不变;   注意哦是已绑定的参数不变。

(function (window, document, undefined) {  
  //   
})(window, document); 

当然只针对我们的例子 其实使用ES6的let声明就解决了。一样输出1,4,9,这里面又能说好多东西呢

function count() {
    var arr = [];
    for (let i=1; i<=3; i++) {
        arr.push(function () {
            return i * i;
        });
    }
    return arr;
}

var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
console.log(f1());
console.log(f2());
console.log(f3());

时间有限,后续在说些闭包其他的东西,个人觉得闭包的重点就是return返回的东西,例如将函数内的私有变量带出,建议看看廖雪峰官网中关于闭包的解释,还有挺多骚操作的。溜了溜了。

 

 

最后 如有错误 欢迎大神指正,不胜感激。

js 闭包

标签:操作   cti   log   个人   例子   概念   函数参数   返回   i++   

原文地址:https://www.cnblogs.com/wds-web/p/8621520.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!