javascript 闭包关于this对象,在闭包函数中为什么会引用全局变量

阮一峰关于 Javascript 中闭包的解读是否正确?
阮一峰有一篇关于javascript 闭包的科普文章:感觉讲的挺好的,考虑到之前被朴灵喷的很惨,所以开始怀疑博文中的讲解是否正确。博文部分观点:1. 我的理解是,闭包就是能够读取其他函数内部变量的函数。2.由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。3.闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
以 “某些說法的確不嚴謹,但也沒必要噴。” 开头的匿名回答是对的。关于闭包的概念,其实就是来自函数式语言。var a = function () {
var test = {};
setTimeout(function () {
console.log(test);
上面的例子中,test在a中定义,但在setTimeout的参数(函数)中对它保持了引用。当a被执行了,尽管a已经执行完(已经执行完),理论上来说a这个函数执行过程中产生的变量、对象都可以被销毁。但test由于被引用,所以不能随这个函数执行结束而被销毁,直到定时器里的函数被执行掉。另外再来个例子:var obj = function () {
var a = '';
set: function (val) {
get: function () {
var b = obj();
b.set('new val');
以上 obj这个函数在执行完之后理论上 函数体内东西都应该被回收掉。但它执行后的返回值 b 具有set和get方法。这两个方法里对a保持了引用,所以obj执行过程中产生的a就不会销毁。直到b先被回收,这个a才会回收。引用维基百科:闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。参照例子 理解下吧。
某些說法的確不嚴謹,但也沒必要噴。比如:函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!不使用 var 等於沒有聲明變量,而是相當於訪問了 window 的屬性。和在 window 下聲明變量的區別在於,訪問 window 的屬性創建的變量可以 delete,在全局作用域下直接聲明的變量不可以 delete。window.b = "hi";
b; // "hi"
delete b; // true
b; // ReferenceError: b is not defined
(function(){c = "hi"}());
c; // "hi"
delete c; // true
c; // ReferenceError: c is not defined
var a = "hi";
a; // "hi"
delete a; // false
a; // "hi"
-----------------回到正題,阮一峰關於閉包的說法也同樣不嚴謹:闭包就是能够读取其他函数内部变量的函数。其它函數,任意其它函數嗎?我們看wikipedia這樣說:閉包是由函式和與其相關的參照環境組合而成的實體。簡單明瞭,既指明了閉包的組成部分,又限定了範圍,比「其它函數」不知高到哪裏去了。況且,閉包只需有擴充變量的作用範圍即可,而無需有其它函數存在。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。混淆了閉包和函數內部定義的函數聲明、函數表達式。即便在函數內部定義了函數,如果沒有引用父函數作用域的變量,也照樣可以不是閉包。函數和環境,缺一不可,這纔是閉包。-----------------爲了通俗而通俗,爲了容易理解而理解,只會使得讀者同樣流於表面,自以爲理解,實際上根本不懂。一旦難度稍微加大,舊有的思維不再好用,就難以提升了。反之一開始就接受抽象思維的訓練而不是套用舊有的思維,雖然一開始艱難,而後必會突飛猛進。建議樓主不要看任何低水平的「科普」文章,直接看英文維基百科、MDN、ECMAScript 草案比較好。真正的入門往往就是在一瞬間,過了這道坎,你就入門了。盲目地看再多低水平的文章,照樣毫無幫助。-----------------知乎的編輯器太不好用了,已被 markdownGM 慣壞。。。
阮一峰的文章是他的学习笔记,并不保证全部正确,因为只是他的理解,而且这篇文章是他09年时写的,可能那时候他的水平比现在还差一些。不过他文章的含金量还是比较高的,同时因为是他的学习笔记,所以我们读起来也通俗易懂。很多初学者可以从阮一峰的文章向高水平进阶,但是通俗易懂的东西一般会存在不严谨的情况。严谨的文章非常好,但是不利于初学者理解。为什么这么说呢,严谨的概念会包含很多对初学者来说十分模糊的专业术语,比如上面答主所提到的:閉包是由函式和與其相關的參照環境組合而成的實體。(原句可能是:A "closure" is an expression (typically a function) that can have free variables together with an environment that binds those variables (that "closes" the expression).)如果是初学者,我相信一看到函式、相关环境等字眼,则直接懵逼。但是阮一峰说:闭包就是能够读取其他函数内部变量的函数。这么解释,只要动动脑,应该可以大概理解闭包是什么东西了。即便这句话很不严谨。所以说阮一峰的文章依然值得看,他的文章可以把你带入一个领域,但是想要正确的认识这个领域,你依然需要去看书,这也是网络文章与实体书的区别。----------------------------------------------想要彻底正确的理解闭包,还是要看、的回答,但是要攒够基础知识。
再提一些个人认为有误导性的地方!Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。搞的好像其他面向对象的语言不能似的。另一方面,在函数外部自然无法读取函数内的局部变量。根本没有提到关键,为什么不能读取内部变量?函数在执行完后会销毁其内部环境这个就没提及。第六个思考题:如果你能理解下面两段代码的运行结果,应该就算理解闭包的运行机制了。var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.
      };
  alert(object.getNameFunc()());
直接不解释this和运行时机制,这又是另一个可以写好几篇文章的知识点。初学者看这片文章是根本看不懂的,甚至会造成误解。强烈建议初学就要看口碑好的书,不要三三两两看博客,那些文章更多的是作者的备忘笔记而已,根本没办法教授你太多东西,甚至作者本身不求甚解。除非你本身就会,然后去看看,巩固加深印象。
闭包就是在函数中使用的未在函数中定义的但在函数所处上下文有效的变量(标识符)与函数本体的集合。
还是严谨一点比较好
闭包确实是js最难理解的东西了,闭包的本质可以说是作用域链形成的要理解闭包,必须要理解这几个概念1.词法作用域2.执行上下文3.活动对象4.scope属性假设如下代码function A(arg1){var v1=1;
var b=function B(){ //执行到这一行定义了函数B,用表达式避免变量提升问题
}}A();一个函数B在定义(声明)时,它在代码树上的上一层函数A此时正处于运行状态(执行上下文指向函数A),此时函数B会生成一个scope属性(函数本质也是对象,可以定义属性),B.scope是一个数组,但是通过代码是访问不到的,通过chome调试面板可以看到,留心的同学可以发现,push了A的活动对象(如果A有上一层函数,会依次push进去),此时B.scope=[{v1:1}],当前函数的活动对象包含了一个函数体内所有var声明的变量,在函数B内部查找变量时优先查找B的活动对象中的变量,如果没有,则遍历scope属性数组中的父级函数活动对象。因为只有在运行时的代码才能声明函数,每一个函数在声明时,父级函数必然处于执行状态,递归思考一下,可知作用域链完全由函数编写时的嵌套顺序所决定,这就是词法作用域的含义,看一个函数的作用域,只要静态分析代码树的结构就行了。所谓的作用域链,其实就是隐含的scope属性一级级的向上引用上一层函数的变量对象,变量对象的查找过程,原理上和对象的属性通过__proto__原型链查找过程差不多。
面新浪的时候,面试官说任何函数都是闭包,我觉得很对啊。阮一峰文中说,他的理解是‘闭包就是能够读取其他函数内部变量的函数’我觉得也很对啊。有些人觉得angular很渣,可是我用的时候很顺手,开发的时候就是很省事,我就觉得angular很棒。所以,只是看法而已,作用在那放着,就是调节作用域,随你怎么用,但是用的时候如果出错,那么肯定就不是闭包了。更新:日10:16:46我上面的回答把作用域和闭包弄混了。不具有参考价值,感谢朴大大指出,受宠若精~~
闭包就是打入敌人内部的间谍,通过他你可以接触敌人对外封锁的信息。
1&2:闭包是用来描述那个函数能够访问那个变量的这种能力的。而不是那个函数也不是那个变量。也就是一个函数能访问其词法范围之外的变量的能力。3:永久保存在内存?只是将对象的生命延长到和使用它的函数一致。如果所有使用它的函数都被回收了,这个变量也就回收了。(好吧,在实践中,这属于钻牛角尖了,而且还要看JS引擎如何实现)闭包在JS中的作用:隐藏私有变量将额外参数传递给运行时生成的函数 (因为你生成的函数会被别人调用,比如回调函数,毫无疑问函数的参数个数和次序已定,但你的函数确实需要更多信息)需要注意的问题:一个变量进入闭包后,会被复制到堆中,所有对该变量的使用都解析为引用这个堆中的变量。所以,使用这个变量的所有函数都会读取到最新的值,而不是你创建该函数时的值。其实 专业一点的JS书中都有解释。
已有帐号?
无法登录?
社交帐号登录闭包与this对象以及window对象
& 这次写的是这三个内容。其实在写之前,会觉得这三个内容很多,但是写了之后会发现,内容确实很多,但是可以写出来的也并不是很多。可能是我总结能力太差。但是这些内容我觉得看实例会比看文字会比较好。恩,第四篇,继续吧。
闭包是指有权访问另一个函数作用域中变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。(闭包就是能够读取其它函数内部变量的函数)
闭包可以读取函数内部的变量,也可以让这些变量的值始终保持在内存中。
闭包会携带包含它的函数的作用域,会比其它函数占用更多的内存,过度的使用闭包可能会导致内存占用过多。
闭包与变量:闭包可以封装一些变量。作用域链的这种配置机制引出了一个副作用,即闭包只能取得包含函数中任何变量的最后一个值。闭包所保存的是整个变量对象,而不是某个特殊的变量
【this对象】
this对象是在运行时基于函数的执行环境绑定的:在全局变量中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。不过,匿名函数的执行环境具有全局性,因此this对象通常指向window。但是在通过call()或apply()改变函数执行环境的情况下,this就会指向其他对象。
this除了以上三种用法外,还有作为构造函数调用。
每个函数在被调用时都会自动取得两个特殊变量:this个arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变量。不过,把外部作域中的this对象保存在一个闭包能够访问到的变量,就可以让闭包访问该对象了。
【window对象】
window是BOM(浏览器对象模型)核心。在浏览器中,window既是通过JavaScript访问浏览器窗口的一个接口,又是ECMAScript规定的Global对象。这意味着在网页中定义的任何一个对象、变量和函数,都以window作为其Global对象,因此有权访问parseInt()等方法。
在全局作用域中声明的变量、函数都会变成window对象的属性和方法。
全局变量不能通过delete操作符删除,而直接在window对象上定义的属性可以。
&窗口关系及框架
如果页面中包含框架,则每个框架都拥有自己的window对象,并且保存在frames集合中。每个window对象都有一个name属性,其中包含框架的名称。
除非最高层窗口是通过window.open()打开的,否则其window对象的name属性不会包含任何值。
在使用框架的情况下,浏览器会存在多个Global对象。在每个框架中定义的全局变量会自动成为框架中window对象的属性。
间接调用和超时调用
JavaScript是单线程语言,但它允许通过设置超时值(在指定的时间过后执行代码)和间歇时间值(每隔指定时间就执行一次代码)来调度代码在特定的时刻执行。
超时调用需要使用window对象setTimeout()方法。语法如下(在一秒钟后显示一个警告框):
setTimeout(function(){
alert("hello word!");
间歇调用的方法是setInterval()。参数方法与超时调用一样。
阅读(...) 评论()闭包中的 this 对象_JavaScript_第七城市
闭包中的 this 对象
关于this对象  在闭包中使用this对象也可能会导致一些问题。this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,&function createFunction(){   alert(this); }; createFunction(); // window&  而当函数被作为某个对象的方法调用时,this等于那个对象。不过,匿名函数的执行环节具有全局性,因此其this对象通常指向 window。  但有时候由于编写闭包的方式不同,这一点可能不会那么明显。&var name = "The Window";  var object = {    name:"My Object",    getNameFunc:function(){      return function(){        return this.      };    }}alert(object.getNameFunc()()); // "This Window 非严格模式下"&
上面代码先创建了一个全局变量 name ,又创建了一个包含 name 属性的对象。 这个对象还包含一个方法--- getNameFunc(),它返回一个匿名函数,而匿名函数又返回 this.name。 由于getNameFunction()返回一个函数,因此调用object.getNameFunc()(),就会立即调用它返回的函数,结果就是返回一个字符串。然而,这个例子返回的字符串是"The Window" 既全局 name 变量的值。
为什么匿名函数没有取得其包含作用域(外部作用域)的this对象尼?
&1& 前面提到过,函数执行时活动对象自动会保存两个值,一个是 this 与 arguments . 内部函数搜索这两个值,只会搜索到其变量对象为止。因此永远不可能直接访问外部
函数中的这两个变量。
不过这可以使用一个变量来保存 this对象,这样就可以访问了 如下var name = "The Window";var object = {  name:"My Object",  getNameFunc:function(){    var _this = this;    return function(){      return _this.    };  }}alert(object.getNameFunc()()); // "My Window 非严格模式下"&上述代码中 _this 变量来保存,而在定义闭包之后,闭包也可以访问这个变量,因为它是我们在包含函数中特意声明的一个变量。
即使返回后调用,其_this任然引用着 object, 所以调用 object.getNameFunc()()就返回了&My Object&
最新教程周点击榜
微信扫一扫JS中的闭包(closure)
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。下面就是我的学习笔记,对于Javascript初学者应该是很有用的。
一.什么是闭包
JS中,在函数内部可以读取函数外部的变量
function outer(){
var localVal = 30;
return localV
outer();//30
但,在函数外部自然无法读取函数内的局部变量
function outer(){
var localVal = 30;
alert(localVal);//error
这里有个需要注意的地方,函数内部声明变量的时候,一定要使用var命令。如果不用的话,实际上是声明了一个全局变量。
function outer(){
localVal = 30;
return localV
alert(localVal);//30
以上的表述,是JS变量的作用域的知识,它包括全局变量和局部变量。
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。
function outer(){
var localVal = 30;
function inner(){
alert(localVal);
return inner;
var func = outer();
func();//30
我们看到在上面的代码中,outer函数内又定义一个函数inner,outer函数的返回值是inner函数,inner函数把localVal alert出来。
我们可以看出以上代码的特点:函数嵌套函数,内部函数可以引用外部函数的参数和变量,参数和变量不会被垃圾回收机制收回。
代码中的inner函数,就是闭包。简单的说,闭包(closure)就是能够读取其他函数内部变量的函数。
由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成&定义在一个函数内部的函数&。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
在上面的代码中,函数inner被包含在函数outer内部,这时outer内部的所有局部变量,对inner都是可见的。但是inner内部的局部变量,对oute 是不可见的。这是Javascript语言特有的&链式作用域&结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
补充--JS中的函数定义
JS中定义一个函数,最常用的就是函数声明和函数表达式
Js中的函数声明是指下面的形式:
function functionName(){
函数表达式则是类似表达式那样来声明一个函数:
var functionName = function(){
我们可以使用函数表达式创建一个函数并马上执行它,如:
(function() {
// local variables
// and the code
()();第一个括号里放一个无名的函数。
二者区别:js的解析器对函数声明与函数表达式并不是一视同仁地对待的。对于函数声明,js解析器会优先读取,确保在所有代码执行之前声明已经被解析,而函数表达式,如同定义其它基本类型的变量一样,只在执行到某一句时也会对其进行解析,所以在实际中,它们还是会有差异的,具体表现在,当使用函数声明的形式来定义函数时,可将调用语句写在函数声明之前,而后者,这样做的话会报错。
二.闭包的应用
使用闭包的好处:
-希望一个变量长期驻扎在内存当中;
-避免全局变量的污染;
-私有成员的存在
1.模块化代码
使用自执行的匿名函数来模拟块级作用域
(function(){
// 这里为块级作用域
该方法经常在全局作用域中被用在函数外部,从而限制向全局作用域中添加过多的变量和函数影响全局作用域。也可以减少如闭包这样的对内存的占用,由于匿名函数没有变量指向,执行完毕就可以立即销毁其作用域链。
var test = (function(){
return function(){
test();//2
test();//3
实现a的自加,不污染全局。
2.循环闭包
循环给每个li注册一个click事件,点击alert序号。代码如下:
var aLi = document.getElementByClassName("test");
function showAllNum( aLi ){
for( var i =0,len = aLi.i&i++ ){
aLi[i].onclick = function(){
alert( i );//all are aLi.length!
点击后会一直弹出同一个值 aLi.length 而不是123。当点击之前,循环已经结束,i值为aLi.length。
利用闭包,建一个匿名函数,将每个i存在内存中,onclick函数用的时候提取出外部匿名函数的i值。代码如下:
var aLi = document.getElementByClassName("test");
function showAllNum( aLi ){
for( var i =0,len = aLi.i&i++ ){
(function(i){
aLi[i].onclick = function(){
alert( i );
function showAllNum( aLi ){
for( var i =0,len = aLi.i&i++ ){
aLi[i].onclick = (function(i){
return function(){
alert( i );
实现解释:
1.作用域链
2.闭包函数的赋值与运行
实际上只是通过函数的赋值表式方式付给了标签点击事件,并没有运行;当遍历完后,i变成标签组的长度,根据作用域的原理,向上找到for函数里的i,所以点击执行的时候都会弹出标签组的长度。闭包可以使变量长期驻扎在内存当中,我们在绑定事件的时候让它自执行一次,把每一次的变量存到内存中;点击执行的时候就会弹出对应本作用域i的序号。
外部无法直接获取函数内的变量,可通过暴露的方法获取
var info = function(){
var _userId = 23492;
var _typeId = 'item';
function getUserId(){
alert(_userId);
function getTypeId(){
alert(_typeId);
info.getUserId();//23492
info.getTypeId();//item
info._userId//undefined
info._typeId//undefined
但是这种方式会使我们在每一次创建新对象的时候都会创建一个这种方法。使用原型来创建一个这种方法,避免每个实例都创建不同的方法。在这里不做深究(一般构造函数加属性,原型加方法)。
4.关于 this 对象
this 对象是在运行时基于函数的执行环境绑定的(匿名函数中具有全局性)(this:当前发生事件的元素),有时候在一些闭包的情况下就有点不那么明显了。
var name = "The Window";
var obj = {
name : "The object",
getNameFunc : function(){
return function(){
return this.
alert( obj. getNameFunc()() )//The Window
var name="The Window"
var obj = {
name : "The object",
getNameFunc : function(){
var _this = this;
return function(){
return _this.
alert(object.getNameFunc()());//The object
javascript是动态(或者动态类型)语言,this关键字在执行的时候才能确定是谁。所以this永远指向调用者,即对&调用对象&者的引用。第一部分通过代码:执行代码object.getNameFunc()之后,它返回了一个新的函数,注意这个函数对象跟object不是一个了,可以理解为全局函数;它不在是object的属性或者方法,此时调用者是window,因此输出是 The Window。
第二部分,当执行函数object.getNameFunc()后返回的是:
function( )
return _this.
此时的_this=this。而this指向object,所以that指向object。他是对object的引用,所以输出My Object。
总结:关于js中的this,记住谁调用,this就指向谁;要访问闭包的this,要定义个变量缓存下来。一般喜欢var _this = this。
5.闭包在IE下内存泄露问题
IE9之前,JScript对象和COM对象使用不同的垃圾收集例程,那么闭包会引起一些问题。
创建一个闭包,而后闭包有创建一个循环引用,那么该元素将无法销毁。常见的就是dom获取的元素或数组的属性(或方法)再去调用自己属性等。例如:
function handler(){
var ele = document.getElementById("ele");
ele.onclick = function(){
alert(ele.id);
闭包会引用包含函数的整个活动对象,即是闭包不直接引用ele,活动对象依然会对其保存一个引用,那么设置null就可以断开保存的引用,释放内存。代码如下:
function handler(){
var ele = document.getElementById("ele");
var id = ele.
ele.onclick = function(){
alert(id);
ele = null;
当然还有其他方法,推荐此法。
三.闭包的原理
当某个函数第一次被调用时,会创建一个执行环境(execution context)及相应的作用域链,并把作用域链赋值给一个特殊的内部属性(即[[Scope]])。然后,使用this、arguncmts 和其他命名参数的值来初始化函数的活动对象(activation object)。但在作用域链中,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象处于第三位,&&直至作为作用域链终点的全局执行环境。
在函数执行过程中,为读取和写入变量的值,就需要在作用域链中查找变量。来看下面的例子:
function compare(valael, value2){
if (valuel & value2){
return -1;
} else if (vaiuel & value2){
return 1;
var result = compare(5, 10);
以上代码先定义了compare()函数,然后又在全局作用域中调用了它。当第一次调用compare()时,会创建一个包含this、arguments、valuel和value2的活动对象。全局执行环境的变量对象 (包含this、result和compare)在compare()执行环境的作用域链中则处于第二位。图展示了包含上述关系的compare()函数执行时的作用域链。
后台的每个执行环境都有一个表示变量的对象&&变量对象。全局环境的变量对象始终存在,而像compare()函数这样的局部环境的变量对象,则只在函数执行的过程中存在。在创建compare()函数时,会创建一个预先包含全局变童对象的作用域链,这个作用域链被保存在内部的[[Scope]]属性中。当调用compare()函数时,会为函数创建一个执行环境,然后通过复制函数的[[Scope]]属性中的对象构建起执行环境的作用域链。此后,又有一个活动对象(在此作为变量对象使用)被创建并被推入执行环境作用域链的前端。对于这个例子中compare()函数的执行环境而言,其作用域链中包含两个变量对象:本地活动对象和全局变量对象。显然,作用域链本质上是一个指向变量对象的指针列表,它只引用但不实际包含变量对象。
无论什么时候在函数中访问一个变量时,就会从作用域链中搜索具有相应名字的变量。一般来讲,当函数执行完毕后,局部活动对象就会被销毁,内存中仅保存全局作用域(全局执行环境的变量对象)。 但是,闭包的情况又有所不同。
function createComparisonFunction(propertyName) {
return function(object1, object2){
var valuel = objectl[propertyName];
var value2 = object2[propertyName];
if (valuel & value2){
return -1;
} else if (valuel & value2){
return 0;
在另一个函数内部定义的函数会将包含函数(即外部函数)的活动对象添加到它的作用域链中。因此,在createComparisonFunction()涵数内部定义的匿名函数的作用域链中,实际上将会包含外部函数createComparisonFunction()的活动对象。图展示了当下列代码执行时,包含函数与内部匿名函数的作用域链。
var compare = createComparisonFunction("name");
var result = compare({ name: "Nicholas" }, { naine: BGreg" });
在匿名函数从createComparisonFunction()中被返冋后,它的作用域链被初始化为包含createComparisonFunction()函数的活动对象和全局变量对象。这样,匿名函数就可以访问在createComparisonFunction()中定义的所有变量。更重要的是,createCoir.parisonFunction() 函数在执行完毕后,其活动对象也不会被销毁,因为匿名函数的作用域链仍然在引用这个活动对象。换句话说,当createComparisonFunction()函数返回后,其执行环境的作用域链会被销毁,但它的活动对象仍然会留在内存中;直到匿名函数被销毁后,createComparisonFunction()的活动对象才会被销毁,例如:
var compareNames = createComparisonFunction("name");
//调用函数
var result = compareNames({ name: "Nicholas" ), { name:"Greg" });
//解除对匿名函数的引用(以便释放内存)
compareNanies = null;
首先,创建的比较函数被保存在变量coinpareNames中。而通过将compareNames设置为等于null解除该函数的引用,就等于通知垃圾问收例程将其清除。随着匿名函数的作用域链被销毁,其他作用域 (除r全局作用域)也都可以安全地销毁了。图 展示了调用conpareNamesO的过程中产生的作用域链之间的关系。
-------------------------------------------------------------------------------------------------------------------------------------
闭包无处不在,弄懂它很重要。
转载需注明转载字样,标注原作者和原博文地址。
阅读(...) 评论()}

我要回帖

更多关于 js 闭包 全局变量 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信