什么是闭包

《你不知道的JS》里有对闭包的定义:“当函数可以记住访问所在的词法作用域,即使函数是在当前作用域之外执行,这就产生了闭包。”

讲闭包是啥的太多了...就一句带过...在我的认知中,就是函数套函数,内部的函数能直接访问外部函数的变量。而外部函数的变量,就能被隐藏起来。从而它的优点是能把这些变量隐藏起来,但它的缺点也是这些隐藏的变量难以释放...

总而言之,就是函数里内嵌函数,当这个函数访问外函数的变量时,就可以叫闭包,而真正实现功能呢,就是在外函数return 出这个内部函数,这样外函数的变量就能达到一个隐藏的效果。

(function fn1(){
var i = 2 ;//变量i就可以被隐藏起来
function fn2 (){
console.log(i) ;//内函数访问了fn1的变量
}
return fn2;
})()

《循环与闭包》

emmmm最开始本来想写闭包的,然后发现闭包没啥好说的......但是在这期间研究《循环与闭包》这一章有所收获。

for (var i = 1 ; i <= 5 ; ++i) {
setTimeout( function timer(){
console.log(i);
} , i*1000);
}//结果是1s后输出一个6,每隔1s输出1个6,共输出5个6

一个很经典的例子...

1.如果没看过这个小例子的人肯定会很疑惑,为什么结果是这个?

​ 首先,我们先讲讲啥是异步,啥是同步.

在我的理解呢,异步就是同时做很多事情,而同步,就是一次只做一件事情

​ 接着我用程序的视角把这个程序运行一遍

​ 首先进入循环,程序接到任务1,setTimeout,我要过i*1000(此时i=1)ms执行timer(由于setTimeout是异步的,它不会等1s执行完timer再继续循环,它接受到了任务1,就说“好了,我记住了,1s后我会执行timer的”,然后一边等1s,一边进入了循环)。接着,它很快就收到了第2个任务——等2s执行timer,以此类推,最后它接到了5个任务,虽然我们这么看是有先后的,但时间太快,所以几乎是瞬间同时完成的...

​ 接着,1s后,第一个任务完成,叮,执行回调函数timer,这个时候又有很一个关键的,因为timer中的i最后检索到的是全局作用域的i,而这时i已经经历完了循环,此时的i=6。同理,直到5s后,第5个任务完成,输出最后一个6。程序演示就到这里结束了。

所以,知道了它的运行过程,我们知道这个程序与预期实现功能——5s每秒依次输出1,2,3,4,5不同的原因,即最后的timer中的i指的是全局的i,我们只要让它指我们所需要的i(1,2,3,4,5)就能实现,我们也很容易找到解决方案。

  • 立即执行函数
for (var i = 1 ; i <= 5 ; ++i) {
(function(i){
setTimeout( function timer(){
console.log(i);
} , i*1000);
})(i);
}
//这里将i立即传进去,形成了封闭的5个函数,timer只能访问到传进去的那个i,也就是我们所需的i。
  • let制造块作用域
for (let i = 1 ; i <= 5 ; ++i) {
//相当于多了一句 var j = i;后面的i也替换为j
setTimeout( function timer(){
console.log(i);
} , i*1000);
}
//这相当于定义了5个不同的i,所以timer找的都是这次运行所对应的i。也就能找到所需的i.

更详细的讲解和拓展可以参考:https://zhuanlan.zhihu.com/p/25407758

Mark一下 https://juejin.im/post/58cf180b0ce4630057d6727c

2.作用域的相关问题

  • 首先,这个程序的作用域结构大致是这样,setTimeout和timer并没有形成闭包,timer也不能访问setTimeout的局部变量。(这是我自己的错,我一直以为这个setTimeout和一个回调函数就可以看作一个闭包的结构....但是通过各种例子证明,回调函数是无法访问setTimeout的局部变量的...)
  • 闭包对于这种循环是一种解决方法。即立即执行函数
for (var i = 1 ; i <= 5 ; ++i) {
(function(i){
setTimeout( function timer(){
console.log(i);
} , i*1000);
})(i);
}

通过闭包,作用域的结构大致是这样。所以timer可以访问匿名函数的变量,即参数i。

  • 当然,还有一点,就是当在某一块作用域RHS寻找某一变量找不到时,它会从定义的地方,向上查找,直到找到为止。就比如说这里的timer,他要找i,它会先找自己内部->找匿名函数->全局。

参考:https://segmentfault.com/q/1010000004486903/a-1020000004486973


emmm....第一次写技术文章,写了自己的一些理解,然后可能这些理解有错,大家可以去知乎或者我mark的一些链接去看...写的不好请见谅

说说循环与闭包——《你不知道的JS》读书笔记(一)的更多相关文章

  1. js读书笔记

    js读书笔记 基本类型的基本函数总结 1. Boolean() 数据类型 转换为true的值 转换为false的值 Boolean true false String 任何非空字符串 "&q ...

  2. 你不知道的javascript读书笔记3

    概述 这是我看<你不知道的JavaScript(中卷)>中关于类型检查的笔记,供以后开发时参考,相信对其他人也有用. typeof 我们知道js中有七种内置类型:undefined, nu ...

  3. <你不知道的JavaScript>读书笔记

    近几天看了一本不错的 JavaScript 的书,是 Kyle Simpson 写的 <You Don't know JS>.这本书是 Kyle Simpson 在 Github 上的开源 ...

  4. d3.js读书笔记-1

    d3.js入门 d3入门 D3是一个强大的数据可视化工具,它是基于Javascript库的,用于创建数据可视化图形.在生成可视化图形的过程中,需要以下几步: 把数据加载到浏览器的内存空间: 把数据绑定 ...

  5. 了不起的Node.js读书笔记

    原文摘自我的前端博客,欢迎大家来访问 http://www.hacke2.cn 第二章 Js概览 基于GoogleV8引擎 Object.keys(o) 数组方法:遍历forEach.过滤filter ...

  6. d3.js读书笔记-2

    比例尺 比例尺基本内容 比例尺是一组把输入域映射为输出范围的函数.任意数据集中的值不可能恰好与图表中的像素尺度一一对应.比例尺就是把这些数据值映射为可视化图形中使用的新值的便捷手段.D3的比例尺就是那 ...

  7. JS闭包—你不知道的JavaScript上卷读书笔记(二)

    关于闭包,初学者会被绕的晕头转向,在学习的路上也付出了很多精力来理解. 让我们一起来揭开闭包神秘的面纱. 闭包晦涩的定义 看过很多关于闭包的定义,很多讲的云里雾里,晦涩难懂.让不少人以为闭包是多么玄乎 ...

  8. 《你不知道的JavaScript(上卷)》读书笔记

    第一次尝试用思维导图记笔记,感觉还不错~~~不过还是改不了我读书笔记写成抄书笔记的毛病 =.= 因为开始学JS的时候,一般浏览器就已经支持ES6了,所以比较喜欢使用ES6语法,let,=>等,文 ...

  9. JavaScript、jQuery、HTML5、Node.js实例大全-读书笔记3

    技术很多,例子很多,只好慢慢学,慢慢实践!!现在学的这本书是[JavaScript实战----JavaScript.jQuery.HTML5.Node.js实例大全] JavaScript.jQuer ...

随机推荐

  1. UIWebView中javascript与Objective-C交互、获取摄像头

    UIWebView是iOS开发中常用的一个视图控件,多数情况下,它被用来显示HTML格式的内容. 支持的文档格式 除了HTML以外,UIWebView还支持iWork, Office等文档格式: Ex ...

  2. (3)Gojs model简介

    (3)Gojs model简介 在GoJS中,model用来存储表的基本数据,包括node.link等具体对象和属性,与其在视觉上的展示效果不相关.model中往往只保存相对简单的数据,最方便且持久化 ...

  3. [模板] Splay

    欠了好久的Splay,以后就它了. 默写真不容易,过几天估计就忘了.. 整个Splay真的精妙,不拖泥带水那种.. 前驱后继之所以不能用rk转到根,是因为这个数不一定存在.. kth中<=老忘记 ...

  4. 关于ie8下disabled属性:字体颜色问题

    在ie8下,input/textarea输入框如果使用disabled属性,字体的颜色会变灰,这时我们可以使用另一种方法实现它. 不使用disabled,用readonly代替: input[read ...

  5. python爬虫学习,使用requests库来实现模拟登录4399小游戏网站。

    1.首先分析请求,打开4399网站. 右键检查元素或者F12打开开发者工具.然后找到network选项, 这里最好勾选perserve log 选项,用来保存请求日志.这时我们来先用我们的账号密码登陆 ...

  6. (九)python3 列表生成式

    列表生成式即 List Comprehensions,是 Python 内置的非常简单却强大的可以用来创建 list 的生成式. 要生成 list [1, 2, 3, 4, 5, 6, 7, 8, 9 ...

  7. Python中关于使用正则表达式相关的部分笔记

    一点点自己记的笔记,如果各位朋友看不懂,可以在评论区留言,会尽可能快的回复. 所有的知识点全部贴在代码上了,注释也写了. 建议大伙把代码拷到自己的机器上,运行,查看结果,然后,结合注释,再自己稍稍理解 ...

  8. Cropping multiple images the same way

    The tools we’ll be using are =GIMP= and =mogrify= (from the ImageMagick suite), so make sure that yo ...

  9. 转载,Django组件

    知识预览 一 Django的form组件 二 Django的model form组件 三 Django的缓存机制 四 Django的信号 五 Django的序列化 回到顶部 一 Django的form ...

  10. xcap发包工具的简单使用2(发送报文)

    上一篇文章介绍了如何构造报文,现在简单讲一下发送报文的步骤 1.获取接口列表 点击主界面工具栏中的“刷新列表”按钮(或对应菜单“interface->Reference interfaces”) ...