前两天看到一个问题说怎样实现add方法实现add(1)(2)(3)结果为6,于是开始引发了我的思考。
1.想要实现add()()这样调用方式,add()方法的返回值务必是一个函数
function add(){ var temp = function(){ return temp; //需要支持多次调用,temp需要返回本身 } return temp; }
2.设计参数
function add(x){ var sum = x; var temp = function(y){ sum += y; return temp; } return temp; }
3.步骤二执行add(1)之后返回的是一个函数,如何实现让他返回累加出来的值呢?这里就要用到黑科技toString方法或者valueOf方法了,原来在上述temp方法中return temp的时候会尝试调用temp.toString或者temp.valueOf方法,因此我们重写toString和valueOf方法在方法内返回sum的值。
function add(x){ var sum=x; function temp(y){ sum+=y; return temp; } temp.toString=function(){ return sum; } return temp; } add(1)(2)(3);//f 6 typeof add(1)(2)(3) //function add(1)(2)(3) == 6 //true add(1)(2)(3) === 6; //false
注意这里add(1)(2)(3)的结果实际上是个function类型的值,实际上要使用还是用'+'转一下。+add(1)(2)(3)结果就是正统的number类型的6啦
关于toString和valueOf的优先级问题:对象在作为操作数时,解释器总是优先调用valueOf()--(Date类型的对象在二元“+”运算时例外),而其他情况,解释器总是认为我们想要的是字符串,所以会优先调用toString(),上述情况就是优先调用toString的情况,因此上面如果只重写valueOf是不会执行自定义的valueOf方法的(没重写toString会调用原型上的)
思考:有办法实现add(1)(2)(3) === 6吗?