zoukankan      html  css  js  c++  java
  • 打老壳的闭包知识

    猜猜下面代码输出什么?

    for (var i = 0; i < 5; i++) {
        setTimeout(function() {
            console.log(i,'b');
        }, 1000);
        console.log(i,'c')
    }
    console.log(i,'a');

    我猜不到啊。。。然后就从一个大神那儿学习了。

    答案是:

    分析:

    由于setTimeout()实现异步的机制,代码console.log(i,'b');被指定到1s后执行,程序会先执行完console.log(i,'c');console.log(i,'a');等他们执行完后再执行console.log(i,'b');

    一、首先,要知道setTimeout()的运行机制:

    setTimeout运行机制

    setTimeout()和setInterval()的运行机制是,将指定的代码移出本次执行,等到下一轮Event Loop时,再检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。这意味着,setTimeout()指定的代码,必须等到本次执行的所有代码都执行完,才会执行。

    Event Loop

    主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环);

    举栗子:

    test1();
    setTimeout(otherTest,1000);
    test2();
    

    其中test1和test2为立即执行任务,otherTest被setTimeout()定时器指定在1s后执行,此时otherTest被添加到任务队列的尾部,要等当前的脚本中Event Loop的任务队列全部执行完成后,才开始执行otherTest,但如果test1和test2耗时很长,前面的任务超过1s还未结束,此时otherTest只能等test1和test2运行结束,才会执行otherTest。

    console.log(1);
    setTimeout(function(){console.log(2);},1000);//如果将setTimeout()的第二个参数设为0,就表示当前代码执行完(执行栈清空)以后,立即执行(0毫秒间隔)指定的回调函数。
    console.log(3);
    

    上面代码的执行结果是1,3,2,因为setTimeout()将第二行推迟到1000毫秒之后执行。

    setTimeout(function(){console.log(1);}, 0);
    console.log(2);
    

    上面代码的执行结果总是2,1,因为只有在执行完第二行以后,系统才会去执行"任务队列"中的回调函数。

    二、什么是闭包?

    内部函数访问外部变量,内部函数被外部函数调用。通俗的讲就是函数a的内部函数b,被函数a外部的一个变量引用的时候,就创建了一个闭包。

    函数内部可以直接读取全局变量,但是在函数外部无法读取函数内部的局部变量。

    栗子:

    function f1(){
      var n=999;
    }
    alert(n); // error

    将最开始的例子代码改为:

    for (var i = 0; i < 5; i++) {
        (function(j) {  // j = i
            setTimeout(function() {
                console.log(j);
            }, 1000);
        })(i);
    }
    console.log( i);
    

    输出的结果为:5 -> 0,1,2,3,4 (使用了立即函数声明)

    闭包的特性:

    ①.封闭性:外界无法访问闭包内部的数据,如果在闭包内声明变量,外界是无法访问的,除非闭包主动向外界提供访问接口;
    ②.持久性:一般的函数,调用完毕之后,系统自动注销函数,而对于闭包来说,在外部函数被调用之后,闭包结构依然保存在
    系统中,闭包中的数据依然存在,从而实现对数据的持久使用。

    优点:

    ① 减少全局变量。

    ② 减少传递函数的参数量

    ③ 封装;

    缺点:
    使用闭包会占有内存资源,过多的使用闭包会导致内存溢出等.

  • 相关阅读:
    数据结构
    java web
    C++
    SQL(结构化查询语言)
    网站协议
    python
    爬虫
    select 多选
    List 去除重复数据的五种方式
    oracle锁表SID查询
  • 原文地址:https://www.cnblogs.com/wgl0126/p/9154689.html
Copyright © 2011-2022 走看看