理解闭包

1、变量的作用域

程序归根结底就是对数据的操作,JavaScript亦是如此。数据都被储存在变量中,用一个变量名进行标识。在同一个程序中可能存在大量的变量,容易产生命名冲突,引起数据操作的混乱,可以想象,早期的程序设计者们一定面临着这样的问题,于是就产生了对变量进行分区划片、隔离处理的需求。这个限定变量作用范围,断绝与外部联系的独立空间就是作用域。

2、JavaScript的作用域

作用域又被称为执行环境。每种语言都有自己对作用域的设定,JavaScript中用于设定作用域的方法非常简单,只有一个,那就是函数(当初函数之所以被设计出来可能就是用来划分作用域的,当然,这只是一个猜测)。函数之内的叫局部作用域,函数之外是一个整体,叫全局作用域。全局作用域就像是大海,而局部作用域就像是一个个互不相干的孤岛,变量不在海上,就在岛内。

3、作用域链

作用域并非简单的一个个独立存在,由于存在嵌套关系,变量的执行环境其实是一个由内向外延伸的作用域链,每个函数的作用域都是从自身出发,沿着嵌套关系向外扩展,直到全局。简单来说就是子函数可以访问父函数的作用域,全局环境作为所有人的“父函数”,可以被所有人访问。这个关系倒过来就不行了,父函数不能读取子函数的变量,在全局作用域中也不能读取函数内部的变量。为什么会是这样?因为JavaScript引擎对标识符的解析就是沿着作用域链由内而外进行的。

4、闭包

闭包是一种特殊的函数结构,它可以“颠覆”上述作用域链设定的访问顺序,实现外部也能访问函数内部的变量。实现的方法很简单,如果函数A想访问函数B中的变量,就在函数B中return函数A,这么做的思路是把函数A打入函数B内部,将B的作用域窃为己有。这样在其它地方调用A,A都能引用B中的变量。看上去很神奇的样子,拿个简单的例子测一下。

果然,虽然是在外面调用的函数son,但也获得了parent内部的变量a

son是在什么时候“偷窃”了函数A的作用域呢?是在创建函数的时候。当引擎解析到function时,就会预先把函数的作用域设置好。所以只要在函数内部定义函数,子函数就会获得父函数的作用域,我们唯一的问题就是无法直接在外部调用子函数,所以要加个return,再通过父函数的调用获得return出来的子函数。

5、使用闭包的注意事项

第一、由于闭包附带的了更多的变量,占用的内存资源也就更多,所以可能导致网页性能问题;

第二、闭包直接继承父元素的作用域,因此对该作用域的修改会影响父元素内部的变量;

第三、闭包继承的父元素作用域中的变量都是“最后的值”,这个看上去就像是面试中容易出现的“陷阱题”,在《JavaScript高级程序设计》和下面给出的廖雪峰的教程中有详细案例和说明。

参考资料:

廖雪峰:http://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/00143449934543461c9d5dfeeb848f5b72bd012e1113d15000

阮一峰:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

《JavaScript高级程序设计》第三版 P178~P182

时间: 2024-11-08 14:15:00

理解闭包的相关文章

ES6之let(理解闭包)和const命令

ES6之let(理解闭包)和const命令 最近做项目的过程中,使用到了ES6,因为之前很少接触,所以使用起来还不够熟悉.因此购买了阮一峰老师的ES6标准入门,在此感谢阮一峰老师的著作. 我们知道,ECMAScript 6即ES6是ECMAScript的第五个版本,因为在2015年6月正式发布,所以又成为ECMAScript2015.ES6的主要目的是为了是JS用于编写复杂的大型应用程序,成为企业级的开发语言. 说明:由于有时候我们希望得知es6代码的具体实现原理或者说希望能够转化为es5使用,

JS 理解闭包

闭包是js的一个难点,许多高级应用都需要用闭包实现.要理解闭包,首先必须理解Javascript特殊的变量作用域,其次是垃圾回收机制. 一.理解变量作用域 ①  变量分为全局变量和局部变量,在函数内部可以直接读取全局变量,如: var a = 100; function x1(){ alert(a); } x1();  //得到 100 而在函数外部,自然无法读取函数内部的局部变量,如: function x1(){ var a = 100; } alert(a);//error ps:如果在函

javascript深入理解闭包

一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function f1(){ var n=999; } alert(n); // error 这里有一个地方需要注意,函数

js深入理解"闭包"

一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function f1(){ var n=999; } alert(n); // error 这里有一个地方需要注意,函数

一步一步的理解闭包

一步步的理解闭包: javascript是函数作用域,按常理来说,一个函数就不能访问另一个函数中的变量. 而我们实际操作有时候需要用一个函数去操作另一个函数中的变量. 为了能够访问另一个函数作用域中的变量,javascript提供一种内部机制,给嵌套在其它函数中的函数提供了一种父作用域链保存机制. 当内部函数创建时,静态的保存了父作用域链,即使父函数执行完毕,其变量对象(这里面保存着我们想要的父变量)一直保存在内部函数的作用域链中.内部函数不再被调用之前,这个活动对象一直在内存中(通俗讲就是这时

JavaScript要理解闭包先了解词法作用域

之所以取名叫做词法作用域,是这个概念是js中相当基础也是极为重要的,很多想当然的错误或感觉怪异的问题都是和这个东西有关.所以,本文主要说下这个名词的概念以及讨论下他牵扯出来的有关变量.函数.闭包的问题. 由变量开始谈 习惯性先来段代码: view source print? 1 var x = "globol value"; 2 var getValue = function() 3 { 4     alert(x);    //弹出"undefined" 5   

JavaScript——以简单的方式理解闭包

闭包,在一开始接触JavaScript的时候就听说过.首先明确一点,它理解起来确实不复杂,而且它也非常好用.那我们去理解闭包之前,要有什么基础呢?我个人认为最重要的便是作用域(lexical scope),如果对作用域和作用域链不理解的同学最好自己先去学一学,再回过头来,理解闭包,就更加轻松. 下面便直接进入主题. 我们知道一个函数是有作用域的,在函数内部定义的局部变量只有在函数内部才可以访问的到.一旦函数访问结束被销毁,局部变量随之也会销毁,无法通过任何方式再次访问局部变量,除了闭包.也就是说

深入理解闭包

闭包之前一直都在看,却总感觉没有深入理解,一直处于云里雾里,今天终于可以炫耀的说我懂了! 闭包是什么? 官方解释我就不说了,只说我理解的吧~ 闭包是提供给外部访问函数内部私有变量的一个接口 一个函数里定义另一个函数就会产生闭包 解释一下: function func() { var a = 10; return function() { return a; }; } var b = func(); console.log(b()); 在函数里定义变量都是私有的,外面无法访问到函数内部,那么,就可

javascript深入理解 `闭包`

简单的例子: function house(){ var num=1;//房子内人的个数: addNum=function(){ //预留的增加函数人数的方法: num+=1; } function query(){//这个函数就叫闭包 alert(num); return num;//返回这个房子的人数 } return query;//返回查询这个房子人数方法的指针及地址: } var res=house();//将这个房子的查询方法的指针/地址赋给变量res; res();//查询房子里面

如何理解闭包?

1.定义: 嵌套在函数作用域中的函数,称为闭包函数.该作用域称为闭包环境.通过闭包函数可以访问闭包函数所在函数作用域中的形参与变量 2.表现形式: 使函数外部能够调用函数内部定义的变量 3.工作原理: 利用了js中的垃圾回收机制,当一个函数被调用时,开辟空间,函数调用结束,释放空间,垃圾回收机制释放被调用结束的函数时,发现函数的变量正在被其他的函数调用,这些变量不会被释放,而且被永久驻留在内存,只有退出程序,才会被释放,或者是手工释放(=null) 4.变量的作用域 要理解闭包,首先必须理解Ja