请教你关于js对象的问题(闭包)

anson_xu 2009-08-17
朋友们好,
    请教你关于js对象的问题(闭包)

this.show = function(id, count){  
        return function(){  
            document.getElementById(id).innerHTML = count<0 ? "over" :count;  
            count--;  
        }  
    }  

请问这段代码中为什么要return function(){


}

为什么不可以直接
this.show = function(id, count){  
       // return function(){  
            document.getElementById(id).innerHTML = count<0 ? "over" :count;  
            count--;  
       // }  
    }


谢谢
beyond-sunbing 2009-08-17
这段代码的目的描述不是很清楚。
实际使用应该是:
//this == obj
var f = obj.show("id", 3);
f();
f();

代码的特点是需要在show函数调用完成后仍然可以访问count参数。
show函数调用时js引擎完成的几个主要的事情如下。
当调用show函数时,js引擎将创建一个活动对象,这个对象将包含函数实参、函数形参、内嵌函数以及内嵌变量等。当经过变量实例化过程后可以将活动对象想象成{arguments:{0:"id", 1: 3, length : 2, callee...}, id : "id", count : 3...}。并将这个对象加入到函数show作用域链的最前端。当定义内部函数时,内部函数的内部属性[[scope]]将指向show函数的作用域链。内部函数作为函数返回值并被外部引用,即构成:f引用show函数定义的内部函数,内部函数的[[scope]]引用show函数执行时创建的活动对象,此时当show函数返回后活动对象依旧被外部通过链的方式引用,js的垃圾回收器也就会回收。也就达到show函数返回后仍然可以访问count参数的目的。
weitao 2009-08-18
上头那哥们,你是在说绕口令吗?
beyond-sunbing 2009-08-18
哥说的不是绕口令是寂寞
j2eebs 2009-08-20
哥,您其实不是寂寞是碎嘴子
meladet 2009-08-20
楼主这段代码,通过return function的方式,形成了一个闭包,闭包是一个由代码与局部变量构成的整体,
为了好理解,可以把它看成C。那么要使用闭包,可以这样
var f = C(id,2); //可以看成是生成了一个闭包的实例,count初始化为2

由于C返回的是一个function,所以变量f实际上是指向了一个function,可以这样执行:
f(); //第一次执行,id元素上显示的是2
f(); //第二次执行,id元素上显示的是1
f(); //第三次执行,id元素上显示的是over

上面可以看出,通过f()实现了一个count递减的效果,而我们直接对count的操作只有在第一次赋值,
之后是通过f()的方式操作。
而如果使用下面代码:
this.show = function(id, count){  
       // return function(){  
            document.getElementById(id).innerHTML = count<0 ? "over" :count;  
            count--;  
       // }  
    } 

这样要达到递减效果,必须每次都调用show(id,count),要把count的值每次都都传进去,
如果不小心传错了。那么就没有办法达到递减的效果

绿生2009 2009-11-12
算递归吗?
summerfeel 2009-11-12
return function我觉得有两个目的:
1.对外部隐藏一个具体的处理过程
2.保留外部函数中的某些局部变量,使其可以在后续过程中继续被访问

这个例子中用到闭包,应该是为了在show函数被调用后,在返回的函数中继续保留和引用id和count的值。
ake87 2010-01-04
meladet 写道
楼主这段代码,通过return function的方式,形成了一个闭包,闭包是一个由代码与局部变量构成的整体,
为了好理解,可以把它看成C。那么要使用闭包,可以这样
var f = C(id,2); //可以看成是生成了一个闭包的实例,count初始化为2

由于C返回的是一个function,所以变量f实际上是指向了一个function,可以这样执行:
f(); //第一次执行,id元素上显示的是2
f(); //第二次执行,id元素上显示的是1
f(); //第三次执行,id元素上显示的是over

上面可以看出,通过f()实现了一个count递减的效果,而我们直接对count的操作只有在第一次赋值,
之后是通过f()的方式操作。
而如果使用下面代码:
this.show = function(id, count){  
       // return function(){  
            document.getElementById(id).innerHTML = count<0 ? "over" :count;  
            count--;  
       // }  
    } 

这样要达到递减效果,必须每次都调用show(id,count),要把count的值每次都都传进去,
如果不小心传错了。那么就没有办法达到递减的效果


够明白
tipx 2010-01-07
函数内部被外部引用

var f = C('id', 2);
在C中return 了一个function,所以此时,f指向C内部的function,而C要析构时,内部的成员function还被外部引用着,所以无法释放,因而形成闭包

C无法释放,则,C中的值自然一直保存着,而此时,那个内部的function直接使用C中的值...just so so...

- -看来我的表达能力的提升空间还相当广阔啊。
Global site tag (gtag.js) - Google Analytics