作为一个前端开发者,闭包是必须要攻克掉的障碍。据说好多面试者挂在闭包面试上。下面我就给大家讲一下我理解中的闭包。不说太多的废话,直接进入主题。

变量作用域

学习编程语言需要明白,变量的作用域。变量作用域分全局变量、局部变量。全局变量尽量少用,因为它很耗费性能。简单理解,全局变量:在任何一个地方都可以访问到。局部变量只有在局部才可以访问到。先举个例子看看:

var data=100;
function domo(){
var data1=20;
console.log(data);
console.log(data1);
}
domo();

可以看出data在dome中也可被访问。所有呢!data是全局变量,data1是局部变量。

闭包

1.常见闭包

/**
* 最简单的闭包
* */
function bibao(){
var d=10;
return function(){
console.log(d);
d++;
}
}
var _bibao=bibao();
_bibao();//输出10
_bibao();//输出11

首先我们要明白函数是有返回值的,如果不手动更改返回值则返回undefined。如何手动更改返回值?就是在函数中使用return 返回。可以返回为布尔值也可以是对象也可以是空字符串也可以是函数。这个最简单的闭包就是返回一个匿名函数。_bibao接收到bibao函数的返回。相当于_bibao===function(){console.log(d);d++;}。然而这个匿名函数中用到了d。此刻_bibao就可以访问d;也可以更改d

2.无return闭包

  1. /**
    * 无return的闭包
    *
    * */
    var _bibao1;
    function bibao1(){
    var d=20;
    _bibao1= function(){
    console.log(d);
    d++;
    }
    }
    bibao1();
    _bibao1();//输出20
    _bibao1();//输出21
    
    

这种没有return 的闭包其实跟上面最简单的闭包是相同的,它只不过把一个匿名函数赋值给全局变量。全局变量此刻保持对这个匿名函数的引用。当调用_bibao1()的时候,就等于调用这个匿名函数。

3.回掉函数中产生的闭包

/**
* 回掉函数中产生的闭包
* @callback {Function} 回掉函数
* */ function bibao2(callback){
var d=100;
setTimeout(function(){
callback()
},2000)
} function _bibao2(){
var d=120;
bibao2(function(){
console.log(d);
d++;
});
setTimeout(function(){
console.log(d);
},3000)
}
_bibao2();//两秒后输出120。三秒后输出121

只有记住一个变量或者参数是一个函数的引用,这个答案就会迎刃而解。执行_bibao2();它会执行bibao2,然后传入一个匿名函数,此刻这个匿名函数保持可以访问到_bibao2中的d。bibao2中的参数callback保持对这个匿名函数的引用。所以它访问的是_bibao2中的d而不是bibao2中的d。

总结

闭包是很有用的,也是很常用的,只有我们记住了它的原理,就能够掌控它们。它只不过是一个函数的引用,这个函数可以访问到这个函数的父函数中的变量而已。

JavaScript 经典之一 闭包的更多相关文章

  1. JavaScript葵花宝典之闭包

    闭包,写过JS脚本的人对这个词一定不陌生,都说闭包是JS中最奇幻的一个知识点,  虽然在工作中,项目里经常都会用到~  但是是不是你已经真正的对它足够的了解~~ 又或者是你代码中出现的闭包,并不是你刻 ...

  2. 和JavaScript家的闭包玩玩捉迷藏

    JavaScript的闭包 首先声明,这是一篇面向小白的博客,不过也欢迎各位大牛批评指正,谢谢.   其实关于闭包各个论坛社区里都有很多的文章来讲它,毕竟闭包是JavaScript中一个特色,也正因为 ...

  3. 深入理解javascript原型和闭包(10)——this

    接着上一节讲的话,应该轮到“执行上下文栈”了,但是这里不得不插入一节,把this说一下.因为this很重要,js的面试题如果不出几个与this有关的,那出题者都不合格. 其实,this的取值,分四种情 ...

  4. 深入理解javascript原型和闭包(15)——闭包

    前面提到的上下文环境和作用域的知识,除了了解这些知识之外,还是理解闭包的基础. 至于“闭包”这个词的概念的文字描述,确实不好解释,我看过很多遍,但是现在还是记不住. 但是你只需要知道应用的两种情况即可 ...

  5. 深入理解javascript原型和闭包 (转)

    该教程绕开了javascript的一些基本的语法知识,直接讲解javascript中最难理解的两个部分,也是和其他主流面向对象语言区别最大的两个部分--原型和闭包,当然,肯定少不了原型链和作用域链.帮 ...

  6. 深入理解javascript原型和闭包系列

    从下面目录中可以看到,本系列有16篇文章,外加两篇后补的,一共18篇文章.写了半个月,从9月17号开始写的.每篇文章更新时,读者的反馈还是可以的,虽然不至于上头条,但是也算是中规中矩,有看的人,也有评 ...

  7. 让你分分钟学会Javascript中的闭包

    Javascript中的闭包 前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它 ...

  8. 深入理解javascript原型和闭包(1)——一切都是对象

    “一切都是对象”这句话的重点在于如何去理解“对象”这个概念. ——当然,也不是所有的都是对象,值类型就不是对象. 首先咱们还是先看看javascript中一个常用的函数——typeof().typeo ...

  9. 深入理解javascript原型和闭包(2)——函数和对象的关系

    上文(理解javascript原型和作用域系列(1)——一切都是对象)已经提到,函数就是对象的一种,因为通过instanceof函数可以判断. var fn = function () { }; co ...

随机推荐

  1. 再起航,我的学习笔记之JavaScript设计模式30(简单模板模式)

    简单模板模式 概念介绍 简单模板模式(Simple template): 通过格式化字符串拼凑出视图避免创建视图时大量节点操作,优化内存开销. 创建模板 在实际的业务中如果我们需要进行前后台交互,或多 ...

  2. django获取ajax的post复杂对象

    一.django的request中post对象为空(即获取不到前台ajax传送的post对象) 1.将django的setting中的django.middleware.csrf.CsrfViewMi ...

  3. python数据结构之栈与队列

    python数据结构之栈与队列 用list实现堆栈stack 堆栈:后进先出 如何进?用append 如何出?用pop() >>> >>> stack = [3, ...

  4. Win CE 6.0 获取手持机GPS定位1----基础知识 (C#)

    一.GPS全球定位系统的组成 (1)GPS卫星(空间部分) 由沿接近环形的地球轨道运行的24颗卫星组成,位于距地表20200千米的高空,均匀分布在6个轨道面上(每个轨道面4颗),轨道倾角55度.此外, ...

  5. Silverlight:telerik RadControls for Silverlight 主题使用心得

    默认情况下: telerik RadControls控件使用的是Office Black 主题,就算在App.xaml.cs里写上 StyleManager.ApplicationTheme = ne ...

  6. 使用邮件监控Mxnet训练

    1. 前言 受到小伙伴的启发,就自己动手写了一个使用邮件监控Mxnet训练的例子.整体不算复杂. 2. 打包训练代码 需要进行监控训练,所以需要将训练的代码打包进一个函数内,通过传参的方式进行训练.还 ...

  7. IOS应用FFMPEG库

    1.引用资源 build-ffmpeg  ffmpeg库生成 -sh开源地址: https://gist.github.com/m1entus/6983547 iFrameExtractor ffmp ...

  8. UWP 绘制图形

    UWP图形和wpf变化不多 一般用到有椭圆.长方形.多边形.线 不过如果用的好,可以做出很漂亮的界面 一般使用画图都是使用Shape 类,Shape 类具有一个与其关联的画笔并可以呈现到屏幕,包括 L ...

  9. Cosmos OpenSSD--greedy_ftl1.2.0(一)

    从主函数跳到ReqHandler,在ReqHandler内先初始化SSD--InitNandReset,然后建立映射表InitFtlMapTable void InitNandReset() { // ...

  10. .net 面试题

    1.列举ASP.NET页面之间传值的几种方式. 答:使用QueryString,如.../id=1;response.Redirect() 使用Session 使用Server.Transfer 使用 ...