博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
打老壳的闭包知识
阅读量:4500 次
发布时间:2019-06-08

本文共 1774 字,大约阅读时间需要 5 分钟。

猜猜下面代码输出什么?

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 (使用了立即函数声明)

闭包的特性:

①.封闭性:外界无法访问闭包内部的数据,如果在闭包内声明变量,外界是无法访问的,除非闭包主动向外界提供访问接口;

②.持久性:一般的函数,调用完毕之后,系统自动注销函数,而对于闭包来说,在外部函数被调用之后,闭包结构依然保存在
系统中,闭包中的数据依然存在,从而实现对数据的持久使用。

优点:

① 减少全局变量。

② 减少传递函数的参数量

③ 封装;

缺点:

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

 

转载于:https://www.cnblogs.com/wgl0126/p/9154689.html

你可能感兴趣的文章
将两个有序链表合并为一个新链表
查看>>
Map接口
查看>>
HDU 1556 Color the ball【差分数组裸题/模板】
查看>>
Codeforces Round #416 (Div. 2) A. Vladik and Courtesy【思维/模拟】
查看>>
Node.js + Express 多个 Layout 文件应用
查看>>
uva 11292 Dragon of Loowater (勇者斗恶龙)
查看>>
leetcode| Intersection of Two Arrays
查看>>
各种反射调用性能测试(赞一个)
查看>>
常用的sql语句
查看>>
51Nod 1301 集合异或和 —— 异或DP
查看>>
[转]十条不错的编程观点
查看>>
JWNL的配置使用 [转]
查看>>
Python的正则表达式
查看>>
【转载】两小时学会用 cocos2d-lua 开发游戏
查看>>
ecshop调用指定栏目下的文章的方法
查看>>
springMVC怎么在一个controller里面跳转,--第一次
查看>>
DAO层,Service层,Controller层、View层
查看>>
ubuntu安装rally
查看>>
Python 迭代器和生成器
查看>>
ASP.NET站点的同时部署给不同的客户。通过数据库配置站点的Top、版权、站点名称...
查看>>