好家伙,总是要来的,去面对那些晦涩难懂的原理,它就在那里,等着我去搞定它

首先我要去补充一些最基本的概念,

1.什么是内存?

新华字典永远的神,

但这个解释显然不够

 

去看看百度百科:

内存:

CPU 能 直接寻址 的 存储空间

2.变量的储存机制

所以,我们假设现在写了一行代码:

var a = 2;

我们将它拆解为两部分

var a;

a=2;

说人话就是:为一个变量分配内存,将其命名为a,然后将2保存进这个变量

 

接着上面的话就是:为一个变量分配CPU 能 直接寻址 的 存储空间,将其命名为a,然后将2保存进这个CPU 能 直接寻址 的 存储空间

3.变量的销毁机制

当一个变量不被需要的时候,就会被销毁,

全局变量不会被销毁,

4.编译原理

var a =2;

这样复杂的语言的,机器是无法理解的

所以我们会需要编译器,

编辑器来这里只干三件事

 

4.1.词法分析

  这个过程将由字符组成的字符串分解成有意义的代码块

4.2.语法分析

  这个过程是将此番单元六转换成一个有元素逐级嵌套所组成的代表了程序语法的结构的数

4.3.代码生成

  转换成机器能听的懂得语言

 

这个其实好理解,就像做英语翻译一样

sun of beach分三步翻译

第一步:拆开 sun,of和beach

第二步:XXX  of  XXX语法

第三步:sun是太阳  of是...的 beach是沙滩

所以翻译就是 沙滩阳光

然后我就能听懂了

5.什么是作用域?

还是那个变量a

我们会这个变量a进行很多操作,例如加减乘除

而当我们操作的时候,我们如何找到他们?

我们需要一套设计良好的规则来储存变量,并且之后可以方便地找到这些变量,

这套规则被称为作用域

                             ----摘自<<你不知道的js(上)>>

作用域指的是当前有权访问的变量集合。

 

JavaScript 拥有函数作用域:每个函数创建一个新的作用域。 作用域决定了这些变量的可访问性(可见性)。

简单的来说,就是:

全局变量全局都能用,

局部变量如下:

// 此处的代码不能使用 carName 变量

function myFunction() {
var carName = "porsche"; // 此处的代码能使用 carName 变量 }

只有局部能用

6.理解闭包

(本篇的主角终登场了)

来看一段展示闭包的代码:

function foo(){
var a =2; function bar(){
console.log(a);
}
return bar;
} var baz = foo(); baz();

//此处输出的结果:2

函数

函数bar()的词法作用域能够访问foo()的内部作用域。

然后我们将bar()函数本身当作一个值类型进行传递。

在这个例子中,我们将bar所引用的函数对象本身当作返回值。

在foo()执行后,其返回值(也就是内部的bar()函数)赋值给变量baz并调用baz(),

实际上只是通过不同的标识符引用调用了内部的函数bar()。

bar()显然可以被正常执行。但是在这个例子中,它在自己定义的词法作用域以外的地方执行。

在foo()执行后,通常会期待foo()的整个内部作用域都被销毁,

因为我们知道引擎有垃圾回收器用来释放不再使用的内存空间。

由于看上去foo()的内容不会再被使用,所以很自然地会考虑对其进行回收。

而闭包的“神奇”之处正是可以阻止这件事情的发生。事实上内部作用域依然存在,因此没有被回收。

谁在使用这个内部作用域?原来是bar()本身在使用。

拜bar()所声明的位置所赐,它拥有涵盖foo()内部作用域的闭包,

使得该作用域能够一直存活,以供bar()在之后任何时间进行引用。

 bar()依然持有对该作用域的引用,而这个引用就叫作闭包。

因此,在几微秒之后变量baz被实际调用(调用内部函数bar),

不出意外它可以访问定义的时候语法作用域,因此它也可以如预期般访问变量a

这个函数在定义时的词法作用域以外的地方被调用.闭包使得函数可以继续访问定义时的词法作用域

                                                            ----摘自<<你不知道的js(上)>>
所以,什么是闭包?

一个函数可引用该函数外部的变量,

function foo(){
var a =2; function bar(){
console.log(a);
}
return bar;
} var baz = foo(); baz();

我要用自己的话说一遍确保我自己理解了:

我调用baz()了,baz()被赋值了,我调用foo(),foo()返回一个bar,bar,打印a

bar把foo的作用域带到了baz中,这个过程发生了闭包,baz用到了变量a

大概就是这样

第九十九篇:JS闭包的更多相关文章

  1. 第十九篇 js高级知识---词法分析和AO 链

    上面一篇文章说了js的作用域链,这一节算是对上面的延申,有一个典型的例子,首先看原来的一段代码: var name = "test"; function t() { var b = ...

  2. Egret入门学习日记 --- 第十九篇(书中 8.8~8.10 节 内容)

    第十九篇(书中 8.8~8.10 节 内容) 开始 8.8节. 重点: 1.类型推断. 2.类型强制转换,使其拥有代码提示功能. 3.除了TS自带的类型判断,Egret官方也提供了类型判断的方法. 操 ...

  3. Python之路【第十九篇】:爬虫

    Python之路[第十九篇]:爬虫   网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用 ...

  4. Bootstrap入门(二十九)JS插件6:弹出框

    Bootstrap入门(二十九)JS插件6:弹出框 加入小覆盖的内容,像在iPad上,用于存放非主要信息 弹出框是依赖于工具提示插件的,那它也和工具提示是一样的,是需要初始化才能够使用的 首先我们引入 ...

  5. “全栈2019”Java第九十九章:局部内部类与继承详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  6. Android UI开发第三十九篇——Tab界面实现汇总及比较

    Tab布局是iOS的经典布局,Android应用中也有大量应用,前面也写过Android中TAb的实现,<Android UI开发第十八篇——ActivityGroup实现tab功能>.这 ...

  7. 第九十六篇:恶补JS基础

    好家伙,来补基础啦,补JS的基础 先来一些概念性的东西 1.什么是JavaScript?  javaScript的简写形式就是JS,一种广泛用于客户端Web开发的脚本语言,常用来给HTML网页添加动态 ...

  8. 第十九篇 -- QTableWidget的使用

    QTableWidget的一些常用方法 下面两个类可以根据自己的情况自定义. 单元格类型的类: class CellType(Enum): ctKey = 1000 ctPath = 1001 ctI ...

  9. Python开发【第十九篇】:Python操作MySQL

    本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy pymsql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb ...

随机推荐

  1. .Net Core 企业微信更新模版卡片消息

    1.搭建回调服务器 可参考:https://www.cnblogs.com/zspwf/p/16381643.html进行搭建 2.编写代码 2.1接口定义 应用可以发送模板卡片消息,发送之后可再通过 ...

  2. uniapp使用scroll-view与swiper组件实现tab滑动切换页面需要注意的问题

    效果图: tab栏可以滑动,切换页面跟随tab栏同步滑动.这里需要注意的是使用swiper组件时,它会有一个默认的高度,你必须动态的获取数据列表的高度覆盖原来的默认高度. 下面是代码 html < ...

  3. RPA SAP财务内部对账机器人

    [简介] 本机器人用于使用SAP软件的集团公司间往来对账前台登录SAP账户和密码,需退出PC微信,输入法切换为英文半角状态. [详细流程] 1.清空Excel-VBA管理工具原始数据 2.输入对账时间 ...

  4. Microsoft Office Visio Professional 之用例图

    1 用例 用例:表示参与者与系统的一次交互过程. 用例用椭圆来表示: 2 用例的特点 用例用于描述系统的功能,这个功能是外部使用者看到的系统功能,不反映功能的实现方式. 用例描述用户提出的一些可见需求 ...

  5. cmd中常用的dos命令

    在电脑中除了我们常见的图形界面之外,图形页面的操作相信都会.那么还有在cmd执行的一些dos命令,可以简单记一下,方便日后复习所用 首先打开cmd窗口,windows+R,然后在对话框输入cmd,进入 ...

  6. 零基础学Java(3)运算符

    运算符 运算符用于连接值.Java提供了一组丰富的算术和逻辑运算符以及数学函数. 算术运算符 在Java中,使用算术运算符+.-.*./表示加.减.乘.除运算.当参与/运算的两个操作数都是整数时,表示 ...

  7. 写了个 Markdown 命令行小工具,希望能提高园友们发文的效率!

    写了个 Markdown 命令行小工具,希望能提高园友们发文的效率! 前言 笔者使用 Typora 来编写 Markdown 格式的博文,图片采用的是本地相对路径存储(太懒了不想折腾图床). 时间久了 ...

  8. Tapdata 实时数据融合平台解决方案(四):技术选型

    作者介绍:TJ,唐建法,Tapdata 钛铂数据CTO,MongoDB中文社区主席,原MongoDB大中华区首席架构师,极客时间MongoDB视频课程讲师. 常见搭建数据中台的技术产品 数据中台包括: ...

  9. 2020 CSP-J 初赛解析

    题面  老师给的解析  自己觉得很好的一篇题解 直接说重点题吧,不耽误时间了 T5: 这个很显然就是让进这个 while 的次数尽可能少, 那么我们可以让他只进一次 while,即让第一次进 whil ...

  10. Java学习第二周

    这一周观看了黑马程序员毕向东的教学视频学习了数组的创建:数组元素的使用及遍历,类的声明,成员方法的声明,构造器的声明 数据类型[] 数组名 = new 数据类型[长度];数据类型[] 数组名 = {数 ...