zoukankan      html  css  js  c++  java
  • 从闭包案例中学习闭包的作用,会不会由你。

      在文章初识js中的闭包中讲解了闭包的一些概念,但是对于初学者来说可能并不是特别的容易理解,我今天用两个案例来解释闭包可能会好理解一些,在讲案例之前,我们需要了解一些闭包的概念。在看这篇文章之前,请先看上面的那篇文章,不然效果不会太好。

    闭包的理解:

      所谓的闭包就是可以创建一个独立的环境,每个闭包里面的环境都是独立的,互不干扰。

    闭包的创建:

      一个函数中嵌套另外一个函数,并且将这个函数return出去,然后将这个return出来的函数保存到了一个变量中,那么就创建了一个闭包。

    为啥要学闭包之没有使用闭包的情况1:

    var arr = [];
    for(var i=0;i<2;i++){
        arr[i] = function(){
            console.log(i);
        }
    }
    arr[0](); //2
    arr[1](); //2

      实际情况我们是要打印0,1,2,3这样的数,但是每次都是打印2,什么情况呢?虽然我们在for中给arr的每个值添加了一个匿名函数,但是在for循环中我们并没有执行这个函数,而是在for循环以后执行的这个函数,那么自然打印出来的就是for循环完以后i的值。

    var arr = [];
    // for(var i=0;i<2;i++){
        var i = 2;
        arr[0] = function(){
            console.log(i);
        }
        arr[1] = function(){
            console.log(i);
        }
    // }
    arr[0](); //2
    arr[1](); //2

      相当于这样,虽然这个函数没有执行,但是arr的i已经给执行了,因为arr不是函数啊,肯定是执行的,而你函数没有调用自然就不会执行,当函数调用的时候i已经是2了。既然如此只要我们在for循环的时候直接执行这个函数就ok。

    var arr = [];
    for(var i=0;i<2;i++){
        arr[i] = function(){
            console.log(i);
        }
        arr[i]();
    }
    //0
    //1

      这样,在每一次for循环的时候就直接执行了这个函数,打印正常,但是我们这样同样有一个问题,那就是在每一次for循环的时候这个函数就已经被执行了,我们要的是我们想什么时候调用就时候调用,而不是直接在for执行中直接执行,那么显然这样做是达不到我们的目的的。

      现在我们在想想闭包的概念,闭包可以创建独立的环境,并且每一个闭包的环境是独立的,也就是说,我们可以通过闭包来保存这些不同的变量。

    var arr = [];
    for(var i=0;i<2;i++){
        arr[i] = function(){
            console.log(i);
        }
    }

      还是这段代码,我们回顾一下闭包的创建方法:一个函数中嵌套另外一个函数,并且将这个函数return出去,然后将这个return出来的函数保存到了一个变量中,那么就创建了一个闭包。

    var arr = [];
    for(var i=0;i<2;i++){
        arr[i] = a(i);
    }
    
    function a(i){
        return function(){
            console.log(i);
        }
    }
    
    arr[0](); //0
    arr[1](); //1

       此时就是一个闭包,这样写有些麻烦,我们对此改进一下。

    var arr = [];
    for(var i=0;i<3;i++){
        arr[i] = (function(i){
            return function(){
                console.log(i);
            }
        })(i)
    }
    
    arr[0](); //0
    arr[1](); //1
    arr[2](); //2

      如果你对()包含起来的函数有些疑惑,对匿名函数的深入理解(彻底版)这篇文章深入的讲解了函数的各种调用方式。如果你没有理解建议你从头再看一遍,当然看不看是你的事,反正我是理解了。

      其实还可以这样

    var arr = [];
    for(var i=0;i<3;i++){
        (function(i){
            arr[i] = function(){
                console.log(i);
            }
        })(i)
    }
    
    arr[0](); //0
    arr[1](); //1
    arr[2](); //2

      此时arr里面的i用的是闭包里面的i,而不是for中的i,因为我们说过每个闭包的环境都是独立的。

    没有使用闭包的情况2:

    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    
    var lis = document.getElementsByTagName("li");
    for(var i=0;i<lis.length;i++){
        lis[i].onclick = function(){
            console.log(i); //3
        }
    }

      这个情况和情况1一样都是因为,这个函数在执行的时候这个for循环已经结束了。

    解决方法:

    var lis = document.getElementsByTagName("li");
    for(var i=0;i<lis.length;i++){
        (function(i){
            lis[i].onclick = function(){
                console.log(i);
            }
        })(i)
    }
  • 相关阅读:
    Oracle常用命令大全(很有用,做笔记)
    表格驱动编程在代码中的应用
    mac 利用svn下载远程代码出现Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo.
    FAILURE: Build failed with an exception.
    There is an internal error in the React performance measurement code.Did not expect componentDidMount timer to start while render timer is still in progress for another instance
    react native TypeError network request failed
    Android向系统相册中插入图片,相册中会出现两张 一样的图片(只是图片大小不一致)
    react-native Unrecognized font family ‘Lonicons’;
    react-native SyntaxError xxxxx/xx.js:Unexpected token (23:24)
    Application MyTest has not been registered. This is either due to a require() error during initialization or failure to call AppRegistry.registerComponent.
  • 原文地址:https://www.cnblogs.com/pssp/p/5224509.html
Copyright © 2011-2022 走看看