什么是闭包

《你不知道的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. 笔试算法题(35):最长递增子序列 & 判定一个字符串是否可由另一个字符串旋转得到

    出题:求数组中最长递增子序列的长度(递增子序列的元素可以不相连): 分析: 解法1:应用DP之前需要确定当前问题是否具有无后效性,也就是每个状态都是对之前状态的一个总结,之后的状态仅会受到前一个状态的 ...

  2. jquery data属性 attr vs data

    html5的自定义data属性相信大家都不会陌生,有了它你可以绑定所需的数据到指定元素上.然后通过jquery设置.获取数据,简直开心的不行啊.想到设置.获取元素属性值,大家一定首先想到了jquery ...

  3. MySQL-----改

    改 **修改用户名** rename user 'username'@'IP address' to 'new username'@'IP address'; **修改密码** set passwor ...

  4. 易维信(EVTrust)支招五大技巧识别钓鱼网站

    网上购物和网上银行凭借其便捷性和通达性,在互联网上日渐流行.在互联网上,你可以随时进行转账汇款或进行交易.据艾瑞咨询发布<2008-2009年中国网上支付行业发展报告>显示:中国互联网支付 ...

  5. FIRST集合、FOLLOW集合、SELECT集合以及预测分析表地构造

    FIRST集合.FOLLOW集合.SELECT集合以及预测分析表地构造 FIRST集合的简单理解就是推导出的字符串的开头终结符的集合. FOLLOW集合简单的理解就对于非终结符后面接的第一个终结符. ...

  6. add favorite & 收藏夹

    add favorite // 收藏夹 function favorite (){ var ctrl = (navigator.userAgent.toLowerCase()).indexOf(&qu ...

  7. 静态区间第k大(主席树)

    POJ 2104为例(主席树入门题) 思想: 可持久化线段树,也叫作函数式线段树,也叫主席树(高大上). 可持久化数据结构(Persistent data structure):利用函数式编程的思想使 ...

  8. tsdb import 相关

    今天一直在做opentsdb 大量导入数据的工作. 中间遇到了一些值得记录的问题, 这里随手记一下 明天好好整理 1. 多进程logger python的logging模块不支持多进程,但我们可以用s ...

  9. maven项目互相dependcy依赖问题

    1.自己编写的maven项目,在编译后,也会在.m2文件夹下生成jar包,可以供第三方引用使用. 2.比如几个项目互相依赖对方的jar包,就要首先选择编译哪个jar包,编译完成后生成jar,再编译依赖 ...

  10. 【Spark】Spark容错机制

    引入 一般来说,分布式数据集的容错性有两种方式:数据检查点和记录数据的更新. 面向大规模数据分析,数据检查点操作成本非常高,须要通过数据中心的网络连接在机器之间复制庞大的数据集,而网络带宽往往比内存带 ...