日期:2014-05-18  浏览次数:20712 次

JS初学者请教

首先请看这个代码

//累加器:闭包作为返回值
function dwn(s)
{
document.write(s + "<br/>");
}
function add(a, b)
{
b = b || 0;
var s = a + b;
//返回一个供进一步累加的闭包
var ret = function(a){
return add(a, s);
}
ret.valueOf = ret.toString = function(){
return s;
}
return ret;
}
dwn(add(5)); //5
dwn(add(5)(10)); //15
dwn(add(5)(10)(20)); //35
dwn(add(5)(10)(20)(500)(500)); //35

这个代码,是我在CSDN一个blog博主这里看过来的,我有2点不明白,希望你解释下:

问题1:我感觉程序是死循环,因为程序没有控制何时结束...

-----------------割------------------------------------------
我注意到程序中有如下一段代码,我不解其意:
       ret.valueOf = ret.toString = function(){return s;}
问题2:
    我尝试着去掉这段代码,则出现了问题,竟然输出了代码本身 !!!
问题3: 
    我又尝试着改写为:ret.valueOf = ret.toString = s ;
这样写照错不误!!!
我很是纠结,希望能指点我一下 ... 

谢谢 ... 

------解决方案--------------------
我猜你认为它是死循环应该是受这影响了
var ret = function(a){
                    return add(a, s);
                }
实际上,这句只是定义ret指向后面的函数,并没有执行它。
等同于 function ret(a){return add(a,s);}

ret是一个function 对象,该对象默认的toString以及valueOf函数是输出函数本身。
而document.write(s + "<br/>");
这句解释器会判定把ret转换为string,首先调用toString函数,不存在时调用valueOf函数。
ret.valueOf = ret.toString = function(){
                    return s;
                }
这句重新定义了上述两个函数为返回闭包内保存的s,
所以执行document.write(s + "<br/>");才会输出那些数字。

ret.valueOf = ret.toString = s ;
这样会把s当做函数执行它,所以会报错。
lz可以打断点调试看下ret对象的结构应该会有帮助!

------解决方案--------------------
引用:
Quote: 引用:

作为你个初学者, 建议你还是先看一些基础的东西吧. 不然你就不会尝试ret.valueOf = ret.toString = s 了

恩,好的!
不过
我所知道的,function(){return s;}是隐式函数,这样是返回s,

而 ret.toString = s 是直接把s给他。

你能指点下不 ?
谢谢 !!!


function(){return s;}
这个函数,它执行了才会返回s。
 ret.valueOf = ret.toString = function(){return s;}
只是定义了valueOf和toString指向的函数,注意只是定义没有执行,它的类型是function
它的执行是在document.write(s + "<br/>"); 隐式执行的,这时才会返回s本身的内容。

你 ret.valueOf = ret.toString = s ;这样写,当执行到
document.write(s + "<br/>"); 时,假设s为15
它执行的是15(),当然出错了。