什么是闭包

《你不知道的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. 聚类和EM算法——K均值聚类

    python大战机器学习——聚类和EM算法   注:本文中涉及到的公式一律省略(公式不好敲出来),若想了解公式的具体实现,请参考原著. 1.基本概念 (1)聚类的思想: 将数据集划分为若干个不想交的子 ...

  2. js 页面图片等元素在普通元素中滚动动态加载技术

    /*! * 2012-01-13 v1.1 偏移值计算修改 position → offset * 2012-09-25 v1.2 增加滚动容器参数, 回调参数 * 2015-11-17 v1.3 只 ...

  3. manacher马拉车算法

    Manacher算法讲解 总有人喜欢搞事情,出字符串的题,直接卡掉了我的40分 I.适用范围 manacher算法解决的是字符串最长回文子串长度的问题. 关键词:最长 回文 子串 II.算法 1.纯暴 ...

  4. 你知道你常用的dos和linux命令吗?

    功能 Linux MS-DOS 进入到该目录 cd cd 列举文件 ls dir 创建目录 mkdir mkdir 清除屏幕 clear cls 复制文件 cp copy 移动文件 mv move 删 ...

  5. 用LAMP构架创建DISCUZ论坛

    # rpm -q httpd mariadb mariadb-server php php-mysql # yum -y install httpd mariadb-server php php-my ...

  6. Ubuntu中Python3虚拟环境的搭建

    1.环境准备 首先请自行安装好Python3和pip3(一般Ubuntu是自带Python3的,可以通过sudo apt-get install python3-pip命令来安装pip3) 安装完成后 ...

  7. 全文搜索(AC-1)-互联网信息过载问题

    什么是信息过载? 信息检索技术是什么? 信息过滤技术是什么?

  8. 【KMP+最小循环节】F. Cyclic Nacklace

    https://www.bnuoj.com/v3/contest_show.php?cid=9147#problem/F [题意] 给定一个字符串,问在字符串后最少添加多少个字母,得到的新字符串能是前 ...

  9. poj 1986tarjan模板题

    #include<iostream> #include<vector> using namespace std; const int N=40010; int pre[N];/ ...

  10. 刺激(codevs 1958)

    题目描述 Description saffah的一个朋友S酷爱滑雪,并且追求刺激(exitement,由于刺激过度导致拼写都缺了个字母),喜欢忽高忽低的感觉.现在S拿到了一张地图,试图制定一个最长路径 ...