38.循环索引同步:利用自执行函数,闭包

2019-06-07  本文已影响0人  Fl_来看看

为什么要同步

for(var i = 0; i < 3; i++){ // 0 1 2 3
        function test() {
            console.log(i); // 3
        }//注意,函数并没有调用执行!!!,只是创建函数而已
    }
    // console.log(i); // 3
    test();

循环索引同步方案一

for(var i = 0; i < 3; i++){ // 0 1 2 3
        function test() {
            console.log(i); // 0 1 2
        }
        test();
    }
    等价于下面【立即执行函数】
       for(var i = 0; i < 3; i++){ // 0 1 2 3
        (function test() {
            console.log(i); // 0 1 2
        })();
    }
    
    又等价于下面
     for(var i = 0; i < 3; i++){ // 0 1 2 3
        // function test(index) { // var index = i;
        //     console.log(index); // 0 1 2
        // }
        // test(i);
        (function test(index) {
            console.log(index); // 0 1 2
        })(i);
    }
(function test(index) {
            console.log(index); // 0 1 2
        })
// 方式一
    (function fun4(){
        console.log("fun4");
    }()); // "fun4"

js中的表达式(expression):js中的一个短语,js解释器会将其计算出一个结果。程序中的常量是最简单的一类表达式。联想,算数表达式,逻辑表达式都会返回一个结果。

let fn=function fun4(){
        console.log("fun4");
    }
    // 方式二
    (function fun5(){
        console.log("fun5");
    })();// "fun4"
    

循环索引同步练习(运用方案一)

let oBtns = document.querySelectorAll("button");
    for(var i = 0; i < oBtns.length; i++) {
        let btn = oBtns[i];
        (function test(index) { // var index = i;
            // console.log(index); // 0 1 2
            
 // 注意点: onclick对应的方法由于满足了闭包的条件,
 // 所以onclick对应的方法也是一个闭包
            btn.onclick = function () {
                console.log(index);
            }
        })(i);
    }

循环索引同步方案二

  var list = [];
    // 这里的i是全局变量
    for(var i = 0; i < 3; i++){ // 0 1 2 3
        var fn = function test() {
            console.log(i); // 3
        }
        list.push(fn);
    }
    // console.log(i);
    // console.log(list);
    list[0]();
    list[1]();
    list[2]();

方案二:用let定义索引

let list = [];
    // 这里的i是局部变量
    // 注意点: 由于i是局部变量, 所以每次执行完循环体都会重新定义一个i变量
    for(let i = 0; i < 3; i++){ // 0 1 2 3
        let fn = function test() {
            console.log(i); // 3
        }
        list.push(fn);
    }
    // console.log(i); // i is not defined
    // console.log(list);
    list[0]();
    list[1]();
    list[2]();

[站外图片上传中...(image-9052fc-1559914641385)]


for(let i = 0; i < 3; i++){ // 0 1 2 3
        // 注意点: 在ES6中由于{}是块级作用域, 所以只要在块级作用域中定义了一个函数
        //         并且这个函数中用到了块级作用域中的数据, 那么这个函数就是闭包
        function test() {
            console.log(i); // 3
        }
    }
    test(); // 2
    

[站外图片上传中...(image-cc159b-1559914641385)]


循环索引同步练习:方案二

    // 在ES6中
    // 1.for循环中通过let定义的变量是一个局部变量
    // 2.for循环中通过let定义的变量每次执行循环体都会重新定义一个新的
    //   也就是每个循环体都有一个属于自己的变量
    
    // 3.for循环中如果定义了函数, 这个函数用到了通过let定义的变量,
    // 那么这个函数是一个闭包
    for(let i = 0; i < 3; i++){
        function test() {
            console.log(i);
        }
    }

    let oBtns = document.querySelectorAll("button");
    for(let i = 0; i < oBtns.length; i++){
        let btn = oBtns[i];
        btn.onclick = function () {
            console.log(i);
        }
    }
    
上一篇下一篇

猜你喜欢

热点阅读