闭包

课时20:内嵌函数和闭包

柔情痞子 提交于 2020-02-13 23:58:56
目录:   一、global关键字   二、内嵌函数   三、闭包   四、课时20课后习题及答案 ******************** 一、global关键字 ******************** 全局变量的作用域是整个模块(整个代码段),也就是代码段内所有的函数内部都可以访问到全局变量。但是要注意一点,在函数内部仅仅去访问全局变量就好,不要试图去修改它。 因为那样的话,Python会使用屏蔽的方式”保护“全局变量:一旦函数内部试图修改全局变量,Python就会在函数内部自动创建一个名字一模一样的局部变量,这样修改的结果只会修改到局部变量,而不会影响到全局变量。看下面的例子: >>> count=5 >>> def myFun(): count = 10 print(count) >>> myFun() 10 >>> count 5 如果觉得有必要在函数中去修改这个全局变量,那么你不妨可以使用global关键字来达到目的!修改程序如下: >>> count=5 >>> def myFun(): global count count = 10 print(count) >>> myFun() 10 >>> count 10 二、内嵌函数 **************** Python函数定义是可以嵌套的,也就是允许在函数的内部创建另外一个函数

装饰器

梦想与她 提交于 2020-02-13 19:56:21
装饰器 在Python这个国家里,装饰器以及后面讲到的迭代器,生成器都是十二分重要的高级函数。 如果将装饰器比作取经路上的一个大boss,那么想干掉它必须拿到三件法宝 法宝一(作用域): 法宝二(函数即对象): 在python的世界里,函数和我们之前的[1,2,3],'abc',8等一样都是对象,而且函数是最高级的对象(对象是类的实例化,可以调用相应的方法,函数是包含变量对象的对象,牛逼!)。 1 def foo(): 2 print('i am the foo') 3 bar() 4 5 def bar(): 6 print('i am the bar') 7 8 foo() 9 # def bar(): #报错 10 # print('i am the bar') 带着这个问题,我们聊一聊函数在内存的存储情况: 图1 函数对象的调用仅仅比其它对象多了一个()而已!foo,bar与a,b一样都是个变量名。 那上面的问题也就解决了,只有函数加载到内存才可以被调用。 既然函数是对象,那么自然满足下面两个条件: 1. 其可以被赋给其他变量 1 def foo(): 2 print('foo') 3 bar=foo 4 bar() 5 foo() 6 print(id(foo),id(bar)) #4321123592 4321123592 2. 其可以被定义在另外一个函数内(作为参数

【JS】关于闭包

怎甘沉沦 提交于 2020-02-12 22:55:33
闭包的概念对于初学者来说很容易理解为“函数里面套函数”,当然这是闭包的典型表现形式,但是为什么要在函数里面套函数呢?要知道在其他语言像Java、C++中都不存在这种方式。 究其原因,谈一谈我的想法,我们知道在ES6出现之前,js中的作用域包括全局作用域和函数作用域,不存在块作用域,当我们想在一个函数内封装一些变量,在其他地方又需要访问这些变量时,闭包就产生了。所以闭包存在的意义就是让我们 可以间接访问函数内部的变量 。 闭包的定义:函数A内有一个函数B,B可以访问A中的变量,函数B就叫做闭包。 // 闭包 function A() { var a = 1; return function B() { console.log(a); } } var a = 2; var bar = A(); bar(); 经典例题: for (var i = 1; i <=5; i++) { function(j){ setTimeout(function() { console.log(j); }, j * 1000) }(i) } 修改使其能正确输出1,2,3,4,5 // 使用闭包 for (var i = 1; i <=5; i++) { (function(j){ setTimeout(function timer() { console.log(j); }, j * 1000) })(i

打老壳的闭包知识

会有一股神秘感。 提交于 2020-02-12 05:46:59
猜猜下面代码输出什么? for (var i = 0; i < 5; i++) { setTimeout(function() { console.log(i,'b'); }, 1000); console.log(i,'c') } console.log(i,'a'); 我猜不到啊。。。然后就从一个大神那儿学习了。 答案是: 分析: 由于setTimeout()实现异步的机制,代码 console.log(i,'b'); 被指定到1s后执行,程序会先执行完 console.log(i,'c'); 和 console.log(i,'a') ;等他们执行完后再执行 console.log(i,'b'); 一、首先,要知道setTimeout()的运行机制: setTimeout运行机制 setTimeout()和setInterval()的运行机制是,将指定的代码移出本次执行,等到下一轮Event Loop时,再检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。这意味着,setTimeout()指定的代码,必须等到本次执行的所有代码都执行完,才会执行。 Event Loop 主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环); 举栗子: test1();

为什么有闭包?

落花浮王杯 提交于 2020-02-12 05:37:39
之前一直认为写博客是个可有可无的事情,前天一个电话面试问得我手足无措,发现很多以前知道的东西现在只能说出个大概,很久没复习的缘故吧。而转身去看的时候,又不知从何看起,顿时觉得有写博客的必要。与日记不同,说不定路过的哪位大神会指出我的错误呢,有趣的讨论还可以加深理解。 什么是闭包? 这个定义一俩句话说出来还真不容易,而且晦涩。 从字面词来讲的话就是一个包裹起来的封闭的东西。百度百科的解释是: 闭包是指可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域) 是不是有点晦涩啊? 哈哈。下面以javascript语言来演示一下闭包: var obj=(function(){ var num=0; return { "getNum":function(){ return num; }, "setNum":function(v){ num=v; } } })(); console.log(obj.getNum());// 0 obj.setNum(3); console.log(obj.getNum());//3 obj

对javascipt闭包的理解(转载自阮一峰大佬的网络日志)

时间秒杀一切 提交于 2020-02-12 04:49:20
转载自阮一峰大佬,方便自己阅读查看 学习Javascript闭包(Closure) 作者: 阮一峰 日期: 2009年8月30日 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 下面就是我的学习笔记,对于Javascript初学者应该是很有用的。 一、变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域。 变量的作用域无非就是两种:全局变量和局部变量。 Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。   var n=999;   function f1(){     alert(n);   }   f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量。   function f1(){     var n=999;   }   alert(n); // error 这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!   function f1(){     n=999;   }   f1();   alert(n); // 999 二、如何从外部读取局部变量? 出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。

到底什么是闭包

时光怂恿深爱的人放手 提交于 2020-02-12 04:49:11
一开始接触闭包有些问题一直绕不过去,可了看其他的资料,也从网上查了查,下面是我总结的一些东西: “官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。 通俗的讲:就是函数a的内部函数b,被函数a外部的一个变量引用的时候,就创建了一个闭包。 (这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b) function a(){ var i=0; function b(){ alert(++i); } return b; } var c = a(); c(); 闭包的特性: ①.封闭性:外界无法访问闭包内部的数据,如果在闭包内声明变量,外界是无法访问的,除非闭包主动向外界提供访问接口; ②.持久性:一般的函数,调用完毕之后,系统自动注销函数,而对于闭包来说,在外部函数被调用之后,闭包结构依然保存在 系统中,闭包中的数据依然存在,从而实现对数据的持久使用。 优点: ① 减少全局变量。 ② 减少传递函数的参数量 ③ 封装; 缺点: 使用闭包会占有内存资源,过多的使用闭包会导致内存溢出等. 最简洁、直击要害的回答,我能想到的分别有这么三句 1、闭包是一个有状态

JavaScript之闭包(重新认识)

我是研究僧i 提交于 2020-02-12 04:24:38
最近又重新学习了闭包,发现之前没有深刻理解作用域链,学习作用域链后对闭包才可以做到真正的理解。 闭包 是指有权另一个函数作用域中变量的函数。要理解闭包首先理解作用域链。 执行环境 定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有与之关联的变量对象,保存了环境中定义的所有变量和函数。只有解析器在处理数据是我才可以访问这个变量。当代码在一个环境中执行时,会创建变量对象的一个 作用域链 ,它保证了执行环境对有权访问的变量和函数的有序访问。 当某个函数被调用时,会创建一个执行环境及相应的作用域链。作用域的最前端,始终都是当前执行代码所在环境的变量对象,下一个变量对象来自外部环境,以此类推,直到全局作用域中的变量对象作为作用域链的终点。作用域链中一定不会包含其内部子函数的变量对象,但子函数的作用域链包含函数的局部变量,因此这决定 创建闭包的方法 是在一个函数内部创建另一个函数,内部函数可以引用外部函数的变量。 闭包与变量 闭包只能取得函数中任何变量的最后一个值,如下创建一个数组函数 function creatFunction(){ var result = new Array(); for (var i=0; i<10; i++){ result[i] = function(){ return i; }; } return result; }

javascript闭包理解

試著忘記壹切 提交于 2020-02-12 03:52:10
1.关于理解闭包之前,理解j s的链式作用域:   子对象会向上寻找所有父对象的变量,即父对象的所有变量对子对象可见;但子对象的变量对父对象不可见; 这句话也可以这么理解:   函数内部可以读取全局变量;函数外部不可以读取函数内部的局部变量; 2.需求:现在想让子对象的变量对父对象可见,或者想在函数外部可以读取函数内部的局部变量,则需要其他方法来实现, 因为 只有函数内部的子函数才能读取全局变量;所以需要 : 定义一个函数并将其作为值返回; 这就是闭包的概念; 3.概念:所以闭包的可以这样理解:能够读取其他函数内部变量的函数; 举例: function f1() { var n = 1; // 闭包 function f2(){ console.log(n); } return f2; } var result = f1(); result(); // 1 4. 关于闭包常见作用: 4.1 如上所说的,可以读取其他函数内部的变量; 4.2 让内部变量的值始终存在内存中,不被回收;  举例: function f1(){ var n=1; nAdd = function(){ //闭包,函数外部对内部进行操作,nAdd是一个全局变量; n+=1; } function f2(){ // 闭包 console.log(n); } return f2; } var result = f1

Javascript闭包

扶醉桌前 提交于 2020-02-12 03:51:41
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 一、变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域。 变量的作用域无非就是两种:全局变量和局部变量。 Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。 Js代码    var n=999;   function f1(){     alert(n);   }   f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量。 Js代码    function f1(){     var n=999;   }   alert(n); // error 这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量! Js代码    function f1(){     n=999;   }   f1();   alert(n); // 999 -------------------------------------------------------------------------------------------------------- 二、如何从外部读取局部变量? 出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下