什么是闭包

《你不知道的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. 神经机器翻译(NMT)开源工具

    博客地址:http://blog.csdn.net/wangxinginnlp/article/details/52944432 工具名称:T2T: Tensor2Tensor Transformer ...

  2. centos7搭建安装sentry

    Sentry 是一款基于 Django实现的错误日志收集和聚合的平台,它是 Python 实现的,但是其日志监控功能却不局限于python,对诸如 Node.js, php,ruby, C#,java ...

  3. CentOS 7.4 源码编译安装 Redis

    一.CentOS 7.4  源码编译安装 Redis 1.下载源码并解压 wget http://download.redis.io/releases/redis-4.0.10.tar.gz tar ...

  4. echarts的简单应用之(一)柱形图

    前段时间做项目需要绘制一些图表来展示信息,从网上资料来看用的比较多的是百度开源的echarts.echarts的官网上有API以及demo.上面的图形都是非常炫的,不过都是静态 数据,我们做项目时不可 ...

  5. 创建Javaweb项目及MyEclipse视图的配置

    在myEclipse里--右键new--Web Project 视图的配置--Window--Show View-Other在里面输入要找的视图例如(servers)或者直接 Window--rese ...

  6. 详解js变量声明提升

    之前一直觉会认为javascript代码执行是由上到下一行行执行的.自从看了<你不知道的JS>后发现这个观点并不完全正确.先来给大家举一个书本上的的例子: var a='hello wor ...

  7. PHP $_SERVER的使用

    常常会用到php的$_SERVER变量,可是好多常用的参数又不熟每次都去查手册.为了记住一些常用的,写个日志吧.前导:网站根目录:/www/domain.com/访问Url:http://www.do ...

  8. codevs——1080 线段树练习

    1080 线段树练习  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 一行N个方格,开始每个格子里都有 ...

  9. java反射与注解结合使用(根据传入对象输出查询sql)

    我们在项目开发中有很多地方使用到了注解,关于注解的定义与创建小伙伴可以参考我的文章<java注解>.有任何问题的小伙伴们可以在评论区指出哦,欢迎各位大佬指出问题. 今天我要说的是使用注解与 ...

  10. 选择判断语句(switch)

    选择判断语句(switch) 一.switch语句格式 switch(表达式){ case 取值1: 执行语句: break: case 取值2: 执行语句: break: …...    defau ...