在开始写这篇文章之前,首先我要跟大家说一下,闭包是前端开发必考的题目,不考的话有两个原因,第一可能出题面试官忘了,第二这家公司的面试官可能没什么水平。

作用域和自由变量

所谓万丈高楼平地起,盘龙卧虎高山齐,在进入闭包的学习之前,我们先要去了解一下作用域的概念,只能说真正理解作用域才能更好地学习闭包,通俗来讲,作用域就是在定义的变量在某个范围内是可使用的一个区域。

简单地画了个图,上述的框框我们可以看出,其实作用域就是某个变量可使用的合法范围,比如变量a,作为全局作用域,是公开使用的,不论是函数外部还是fn1,2,3都可以使用,就好比公厕这种地方是面向全社会人员的。我们再看看fn3,假如fn2,fn1或者函数外部需要使用或者修改a3这个变量,是无法使用的。

在这里顺便讲一下自由变量,自由变量就是一个变量在当前作用域没有定义,但被使用了,我们再来看看这张图

这个代码段的执行顺序是,先调用fn1()、fn2()、fn3() ,当执行fn3()的时候,返a + a1 + a2 + a3,因为在fn3()的作用域没有a2,a1,a所以要往上一层fn2寻找,fn2没有a1,a所以再往上一层fn1找,fn1没有a,所以最后要到全局作用域才能找到a。因为a2,a1,a不在fn3的作用域范围,所以它们可称为自由变量

再啰嗦多一句,如果全局作用域都没找到的变量,则会报错——xx is not defined

闭包

上述的讲解同学们应该可以了解到了作用域到底是神马东西了,那么闭包这玩意,其实就是作用域的特殊情况,它有两种表现:

1.函数作为参数传递

2.函数作为返回值返回

我们先看看两个代码片段

// 函数作为返回值function fun (){const a = 100;return function(){console.log(a);//100}}const fn = fun();const a = 200;fn();
 // 函数作为参数被传递function print(fn){const a = 200;fn();}const a = 100;function fun (){console.log(a);//100}print(fun);

解释一下控制台的打印结果,为什么是100呢,上面的内容已经讲解到,自由变量往往不存在当前的作用域范围中,所以需要一层一层地往上寻找,console.log(a)里面的变量a在函数中未被定义,所以需要往上一层寻找自己被定义和赋值的地方。

闭包的应用

我们先看一个代码片段

 // 闭包隐藏数据,只提供APIfunction Cache(){// 闭包中的数据被隐藏,不被外界访问const data = {};return{set: function(key,val){data[key] = val},get: function(key){return data[key]}}}const t = Cache()t.set('money',100)console.log(t.get('money'));//100

上述代码中,我们简单做了一个Cache工具,在函数返回值返回两个函数,set用于传值,get用于取值,最后在控制台中打印出100。那我们能不能直接修改data的值?

 // 闭包隐藏数据,只提供APIfunction Cache(){// 闭包中的数据被隐藏,不被外界访问const data = {};return{set: function(key,val){data[key] = val},get: function(key){return data[key]}}}data.b = 200 //控制台会报错

相信同学们已经知道为什么data.b = 200不可行吧,原因就是作用域问题,data是在Cache函数的作用域中,作用域外面并不能获取到它的值。所以这里函数主要的功能是只提供API,那么闭包中的data数据则由它自己来管理,外界无法修改。

今天你学废了吗?

JavaScript闭包(必考三座大山之二)相关推荐

  1. JavaScript异步(必考三座大山之三)——第四集:async-await

    前言 现在使用JavaScript开发的异步编程,基本上被async-await承包了,所以这个东西你不能不会. 第三集我们讲解到,要想解决异步的回调地狱,可以使用Promise对象里面内置的方法th ...

  2. (六)JS基础知识三(走进作用域和闭包)【三座大山之二,不会闭包,基本不会通过】

    JS基础知识三(作用域和闭包) 提问 作用域 自由变量 闭包 this 提问 this的不同应用场景,如何取值 手写bind函数 实际开发中闭包的应用场景,举例说明 创建10个a标签,点击的时候弹出对 ...

  3. 今日头条面试必考:Hadoop 二次开发,90%的人都栽这了!

    大数据由于数据量庞大.数据类型复杂等特点,特别是非结构化或半结构化数据远远多于结构化数据,导致传统关系型数据库让企业面临巨大的成本压力.而 Hadoop 能够很好的提供解决大数据问题的技术手段.因此, ...

  4. 今日测试:javascript笔试必考

    明天就是周末了,有点小激动!大伙来做到小题目先,闲话不多说,直接上题目! <script> for(var i=0;i<5;i++){ setTimeout(function(){ ...

  5. 山西中考计算机知识点,2018年山西省中考必考语文知识点

    保证睡眠充足和睡得好才能打好提高复习效率的"持久战",当然学习是不可少的,关于中考语文的考点大家知道多少呢?下面是由学习啦小编为大家整理的2018年山西省中考必考语文知识点,希望大 ...

  6. JavaScript进阶必会的手写功能(二)

    JavaScript进阶必会的手写功能(一) 6. 手写浅拷贝 6.1 JavaScript数据类型分类 1. 简单数据类型: Number. String.Boolean.null.undefine ...

  7. 最全Java面试208题,涵盖大厂必考范围!强烈建议收藏~

    这些题目是去百度.小米.乐视.美团.58.猎豹.360.新浪.搜狐等一线互联网公司面试被问到的题目,熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率. 一.java基础面试知识点 java中= ...

  8. 2018 BAT最新《前端必考面试题》

    2018 BAT最新<前端必考面试题> 1.Doctype作用? 严格模式与混杂模式如何区分?它们有何意义? (1). 声明位于文档中的最前面,处于 标签之前.告知浏览器的解析器,用什么文 ...

  9. Javascript闭包和闭包的几种写法及用途

    好久没有写博客了,过了一个十一长假都变懒了,今天总算是恢复状态了.好了,进入正题,今天来说一说javascript里面的闭包吧!本篇博客主要讲一些实用的东西,主要将闭包的写法.用法和用途.  一.什么 ...

最新文章

  1. MySQL出现同步延迟有哪些原因?如何解决?
  2. 3、假设有一个对象数组,想根据某个对象属性对数组进行排序时
  3. iOS Xcode 项目重命名
  4. Linkedin工程师是如何优化他们的Java代码的
  5. android不能使用udp获取数据解决
  6. RANSAC与 最小二乘(LS, Least Squares)拟合直线的效果比较
  7. AJAX之表单即时验证
  8. 漫步最优化二十五——斐波那契搜索
  9. SecureCRT 回车按键值修改
  10. 二叉树:层序遍历登场!
  11. 【Tensorflow】【损失函数】交叉熵数据验证(上)---CategoricalCrossentropy多分类
  12. html如何判断ie版本,在html中判断IE浏览器的版本
  13. 使用MVPArms框架时,访问网络没响应。
  14. 桌面计算机图标双击打不开了,双击打不开图标怎么办 双击打不开图标解决方法【详解】...
  15. 看云|专注于文档在线创作、协作、分享和托管
  16. 画外因 | 笛卡尔与瑞典女王在 “数学课”上谈人生
  17. 51单片机生成二维码
  18. IE浏览器如何导入导出收藏夹
  19. 经济管理专业必备的15种国内数据库推荐
  20. Image Pyramid

热门文章

  1. WPS如何批量合并相同单元格
  2. 译文 | 创造性思维的脑暴如何激发?
  3. 【支付】世界六大银行卡组织
  4. 面试 C++ 后台开发会考察哪些问题?
  5. 两千到三千的手机买那些?看看这些媲美旗舰的手机,华为只有一款
  6. 分享一次前端小白的面试题
  7. 总结了10句话,送给所有的通信新员工
  8. 杏子语录(2019年08月)
  9. 谭浩强《C程序设计第五版》笔记㈠
  10. Kafka.Day.线上问题优化