简体   繁体   中英

Javascript Nested functions with toString

Can anyone please explain this code? This example is taken from javascript.info.

I don't understand, especially the f.toString = function(){ return sum} part.

function sum(a) {

   var sum = a 

   function f(b) {
       sum += b
       return f
   }

   f.toString = function() { return sum }

   return f
}

alert( sum(1)(2) )  // 3

alert( sum(5)(-1)(2) )  // 6

alert( sum(6)(-1)(-2)(-3) )  // 0

alert( sum(0)(1)(2)(3)(4)(5) )  // 15

All objects in javascript 'inherit' a field called toString that exists on the prototype of boject. After assignment toString exists as any other field on f. It is assigned a as a function, and can be invoked as such:

Basically, sum is a function that can be chained into multiple calls. toString is a method of the object that returns what should be shown if the object is used in a context that expects a string.

Personally, I think it'd be easier like this:

function sum() {
    var l = arguments.length, i, a = 0;
    for( i=0; i<l; i++) a += arguments[i];
    return a;
}
alert(sum(1,2));
alert(sum(5,-1,2));
alert(sum(6,-1,-2,-3));
alert(sum(0,1,2,3,4,5));

I think the author of that snippet wanted to achieve one goal, that is, something like "faking" operator overloading which is possible in other languages.

Since sum returns a function reference , we could not go like

sum(5) + 5;

That would result in something weird like "function sum() { ... }5" . That is because ECMAscript calls the .toString() method on objects when invoked in a Math operation. But since he overwrites the .toString() method returning sum (which is a number), it does work again.

Here is a snippet from MDN article about Function.toString

The Function object overrides the toString method inherited from Object; it does not inherit Object.prototype.toString. For Function objects, the toString method returns a string representation of the object in the form of a function declaration. That is, toString decompiles the function, and the string returned includes the function keyword, the argument list, curly braces, and the source of the function body.

JavaScript calls the toString method automatically when a Function is to be represented as a text value, eg when a function is concatenated with a string.

So basically, what this "annoying" piece of code is doing is providing an implementation for Function.toString that will be used when when a string representation is required, ie when alert is called ( alert takes a string as an argument).

For the rest of the code, it's just calling itself recursively to compute the sum of the arguments.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM