闭包

js闭包

会有一股神秘感。 提交于 2020-02-12 00:06:43
啥是闭包? 闭包是能读取其他函数内部变量的函数,js中能读取一个函数内部变量的只有该函数的后代函数,在函数的外部是访问不了函数的变量的. 需要操作某个函数的内部变量时,不能把所有的操作都放在函数内部,这样就需要内部函数作为一个桥梁,将函数的信息输送出来 注意一点,在函数内部声明变量时必须要使用var,否则系统会认为你声明的是一个全局变量 声明变量时,如果不写var,系统会认为声明的是window.a,即window对象的属性 闭包有啥用? 1.可以防止全局的命名空间被污染   --如果要写一个累加器,不使用闭包的话,就必须定义一个全局的变量来接收 var count = 0; function add(){ count++; console.log(count); }     //每次调用add函数count就会加1 add(); add(); add();     //这个函数如果count变量放在函数内部,每次调用函数时count都会被重置为0,不能达到累加的作用     //如果使用闭包就不会出现这一问题 2.便于模块化开发 使用闭包开发的项目各个功能都被封装到了各自的函数中,之间互不影响 3.安全性 将变量都变为私有的,只有通过内部函数才能访问函数的变量,能够提高成程序的安全性 闭包咋写啊? 上面的例子如果写成闭包的形式就是这样: function add(){ var

JS闭包那些事

会有一股神秘感。 提交于 2020-02-12 00:05:28
关于闭包,我曾经一直觉得它很讨厌,因为它一直让我很难搞,不过有句话怎么说来着,叫做你越想要一个东西,就要装作看不起它的样子。所以,抱着这个态度,我终于掳获了闭包。 首先来认识一下什么是闭包,闭包,一共有三大特征: 1 函数嵌套函数 2 内部的函数可以引用外部函数的参数和变量 3 参数和变量不会被垃圾回收机制所收回 举个栗子: function aaa(){ var b = 5; function bbb(){ b++; alert(b); } } aaa(); 这个栗子就是很明显的闭包,函数里面嵌套函数,同时内部的函数bbb又可以访问到外部函数aaa中的变量,至于第三个特征,我们都知道在JS解析机制中,函数内的变量在函数调用完后会被销毁,但在这里b并没有被销毁,因为他还会被里面的函数bbb引用,那么怎么证明呢? 首先,我们要注意,在上面这个栗子中,是不会弹出值的,因为里面的函数bbb,只是声明了,并没有被调用,我们都知道,函数它不会主动执行的,那么怎么执行呢,看下面: function aaa(){ var b = 5; function bbb(){ b++; alert(b); // 6 } return bbb; } var c = aaa(); // 此时aaa被执行 同时把返回结果bbb 赋给c c(); //6 将里面的函数作为返回结果,然后可以调用,这种经常会遇见

简单详细讲解js闭包(转载)

不问归期 提交于 2020-02-11 21:03:16
闭包,其实是一种语言特性,它是指的是程序设计语言中,允许将函数看作对象,然后能像在对象中的操作般在函数中定义实例(局部)变量,而这些变量能在函数中保存到函数的实例对象销毁为止,其它代码块能通过某种方式获取这些实例(局部)变量的值并进行应用扩展。 我们的理解: 其实闭包就是一个函数,一个外部函数通过调用函数并return返回出内部函数,这里的内部函数就是一个闭包;此时在内部函数中是可以访问到外部函数的变量的; 要想理解闭包,首先我们要了解栈堆内存和作用域链;首先我们来讲解栈堆内存: 首先我们来看个demo: var a=1; var obj={"name":"咸鱼"} 上面简单的两句代码,其实就是在内存中做了两件事,效果图如下: 在js简单实现深浅拷贝(https://www.cnblogs.com/dengyao-blogs/p/11466598.html)一文中我们知道基本数据类型是存储在栈内存中的,引用数据类型是存储在堆内存中的,其实上面的两句代码在内存中就是做了两件事: 1.首先在栈内存中开辟了一块空间用来存放a的变量和值; 2.在堆内存中开辟了一块空间用来存储obj的值,同时在将地址指向栈内存中的变量名obj 如果我们在代码下面再加上一句obj={"name":'张三"},这个时候我们之前存储name为咸鱼的值也就是obj原来的值会被js中的垃圾回收机制回收掉

浅析 JavaScript 中的闭包(Closures)

两盒软妹~` 提交于 2020-02-11 05:10:07
/*--> */ /*--> */ 一、前言 对于 JavaScript 来说,闭包是一个非常强大的特征。但对于刚开始接触的初学者来说它又似乎是特别高深的。今天我们一起来揭开闭包的神秘面纱。闭包这一块也有很多的文章介绍过了,今天我就浅谈一下自己对闭包的的一些理解,希望能提供一点鄙陋的见解帮助到正在学习的朋友。该文章中能使用口语化的我将尽量使用口语化的叙述方式,希望能让读者更好理解,毕竟文章写出来宗旨就是要让人读懂。文章难免有不足之处还希望帮忙指出。 二、Javascript 的作用域链 在了解闭包之前,我们先来看看几个准备知识。 变量的作用域 首先,什么是作用域?域,区域。简单来理解就是一个变量能被访问的范围(区域)。换言之就是这个变量能起作用的区域。按这个标准来划分我们将变量分为 全局变量 和 局部变量 两种 以定义的方式来区分有以下特点: 定义在函数内部的变量是局部变量,定义在函数外部的变量是全局变量。(这个并不只是 Javascript 语言的特点)局部变量在函数内部能被访问,在函数外部不能被直接访问,所以局部变量就是从定义它的地方开始到函数结束的位置结束。当然这里有个细节-- 变量声明提升 。等下我们用一小段代码提一下变量声明提升是什么。我们先来看看局部变量和全局变量的代码 var a = 0; function testFunc(){ var b = 1; console

深入理解JavaScript系列(14):作用域链(Scope Chain)

给你一囗甜甜゛ 提交于 2020-02-11 04:55:43
前言 在第12章关于变量对象的描述中,我们已经知道一个执行上下文 的数据(变量、函数声明和函数的形参)作为属性存储在变量对象中。 同时我们也知道变量对象在每次进入上下文时创建,并填入初始值,值的更新出现在代码执行阶段。 这一章专门讨论与执行上下文直接相关的更多细节,这次我们将提及一个议题——作用域链。 英文原文:http://dmitrysoshnikov.com/ecmascript/chapter-4-scope-chain/中文参考:http://www.denisdeng.com/?p=908本文绝大部分内容来自上述地址,仅做少许修改,感谢作者 定义 如果要简要的描述并展示其重点,那么作用域链大多数与内部函数相关。 我们知道,ECMAScript 允许创建内部函数,我们甚至能从父函数中返回这些函数。 var x = 10; function foo() { var y = 20; function bar() { alert(x + y); } return bar; } foo()(); // 30 这样,很明显每个上下文拥有自己的变量对象:对于全局上下文,它是全局对象自身;对于函数,它是活动对象。 作用域链正是内部上下文所有变量对象(包括父变量对象)的列表。此链用来变量查询。即在上面的例子中,“bar”上下文的作用域链包括AO(bar)、AO(foo)和VO

前端常见面试题:闭包

允我心安 提交于 2020-02-10 22:25:59
js闭包: 闭包就是指可读取其他函数的局部变量。 只有函数内部子函数才能读取局部变量。 闭包就是函数内部能读取函数外部数据一个桥梁。以下f2为闭包。 function f1(){ n=999 function f2(){ alert(n) } return f2 } 闭包的作用: 可读取上例中函数内部的变量n 让内部变量n值永远存在内存中。 缺点: 很可能造成内存泄露。 来源: CSDN 作者: lucky_girl_girl 链接: https://blog.csdn.net/lucky_girl_girl/article/details/104253277

PHP学习笔记06-静态变量、回调函数、匿名函数、闭包

余生颓废 提交于 2020-02-10 20:53:03
1.静态变量修饰符static 使用static修饰变量可以使函数之间跨函数共享数据 如上图所示,static修饰变量b后,调用三次函数,变量b的值都在增加,而没有static修饰的变量a,每次调用的变量都是1。 2.可变函数 假如变量的值是一个函数名称,则可以直接在改变量之后加上括号即可调用改函数。 3.回调过程和回调函数 我们一般把一个函数传入给另一个函数去使用,这个过程称之为回调函数,而被传入的函数叫回调函数。 函数sys_num我们可以称之为回调函数。 4.匿名函数 匿名函数就是没有函数名的函数。 变量保存匿名函数,实际上得到的是一个对象。 5.闭包 闭包实际上就是提供了一个环境,使内部匿名函数可以访问局部变量。 没有使用闭包时: 使用闭包时: 使用use关键字可以让变量不会被释放,提供一个环境给匿名函数使用。 来源: CSDN 作者: weiweiQAQ 链接: https://blog.csdn.net/qq_42062052/article/details/104225072

Python3(九) 闭包

◇◆丶佛笑我妖孽 提交于 2020-02-10 20:26:16
一. 一切皆对象 函数式编程并没有标准定义,如果代码非常繁琐则考虑使用。 学习闭包的概念,不是python独有的。 其他大多数语言中的函数只是一段可执行的代码,并不是对象。 python中的函数是对象,一切皆对象。可以把函数赋值给变量: a = 1 a = '2' a = def 甚至可以把函数当作另外一个函数的参数传递或者当成返回值返回,而C#中要封装成委托。 二.什么是闭包:闭包=函数+函数定义时的环境变量 我们尝试从概念上去理解一下闭包。 在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。—— 维基百科 用比较容易懂的人话说,就是当某个 函数 被当成对象返回时, 夹带了外部变量 ,就形成了一个闭包。 1. code1 def curve_pre(): def curve(): pass curve() #找不到,因为curve()的作用域仅限于curve_pre()的内部 code2 def curve_pre(): def curve(): print('This is a function') pass return curve #函数可以作为结果返回 f = curve_pre() #函数可以赋值

闭包和装饰器

ぃ、小莉子 提交于 2020-02-10 17:45:12
闭包 当一个函数在内部定义函数,并且内部的函数应用外部函数的参数或者局部变量,当内部函数被当做返回值时,相关参数和变量保存在返回的函数中,这种结果叫闭包。 # 闭包结构,myF5用到了myF4的参数args def myF4 ( * args ) : def myF5 ( ) : rst = 0 for n in args : rst += n return rst return myF5 # 常见的闭包错误 def count ( ) : # 定义列表,列表里存放的是定义的函数 fs = [ ] for i in range ( 1 , 4 ) : # 定义了一个函数f # f是一个闭包结构 def f ( ) : return i * i fs . append ( f ) return fs f1 , f2 , f3 = count ( ) print ( f1 ( ) ) print ( f2 ( ) ) print ( f3 ( ) ) # 此时的输出会是9,9,9,并不是我们想要的1,4,9 造成上述状况的原因是,返回函数引用变量i,i并非立即执行,而是等到三个函数都返回的时候才统一使用,此时i已经变成了3,最终调用的时候,都是返回3*3 此问题描述成: 返回闭包时,返回函数不能引用任何循环变量 解决方案: 用函数的参数绑定循环变量的当前值,无论该循环变量以后如何改变

闭包的实际应用之函数节流和函数防抖

大城市里の小女人 提交于 2020-02-09 21:56:11
闭包是个老生长谈的问题,本文不说什么是闭包,说说闭包在实际中的应用,我们可以使用闭包来实现函数节流和函数防抖 函数节流 const throttle = ( fn , wait ) => { let preTime = Date . now ( ) return function ( ) { if ( Date . now ( ) - pre > wait ) { fn ( ) preTime = Date . now ( ) } } } 函数防抖 const debounce = ( fn , wait ) => { let timer = null return function ( ) { if ( timer ) { clearTimeout ( timer ) } timer = setTimeout ( fn , wait ) } } 小结 这里简单的介绍了通过闭包实现了函数节流和函数防抖,核心是 throttle 函数中的 preTime 和 debounce 的函数中的 timer 变量来判断实现函数节流和防抖。 来源: CSDN 作者: TyrionJ 链接: https://blog.csdn.net/TyrionJ/article/details/104238761