Search code examples
javascriptargumentssymbol-table

How to re-assign the arguments of a function back to the original argument names?


I have a function which rearranges the arguments of another function to meet a standard defintion.

function main(a, b, c) {
    console.log(a, b, c);                                  // 1 undefined undefined
    console.log(arguments[0], arguments[1], arguments[2]); // 1 undefined undefined

    shiftArgs(arguments, 3); // 3 because I'm expecting 3 arguments.

    console.log(arguments[0], arguments[1], arguments[2]); // null null 1
    console.log(a, b, c);                                  // 1 undefined undefined ***
}



function shiftArgs(args, c) {var i, len; 
   len = args.length; 
   if (len < c) { 
      for (i = c - 1; i >= 0; i -= 1) {
          args[i] = ((i - c + len) >  -1 ? args[i - c + len] : null);
      }
      args.length = c;
   }
};

main(1); // only calling main with one argument, which therefore needs to be the last one.

*** is the problem line and should be "null null 1" to match the reassigned arguments object.

The arguments object is changed as I want, with the value "1" called by main moved to the last argument. However, the variable names that map to the arguments don't get changed after I move the arguments object around (see the last console.log marked with ***). This needs to be null null 1 to match the changed arguments object).

How can I have the variables a, b, & c be reassigned by the shiftArgs function to match the arguments object?


Solution

  • You don't want to mess with the arguments object like that. That parameter variables are mapped to it is considered buggy, it won't work in strict mode either.

    Better use a function decorator for such things:

    function shiftArgs(fn, c) {
        return function() {
            var lastIdx = arguments.length; 
            if (arguments.length < c)
                for (var i = c-1; i >= 0; i--)
                    arguments[i] = ((i - c + lastIdx) >  -1 ? arguments[i - c + lastIdx] : null);
            arguments.length = c;
            return fn.apply(this, arguments);
        };
    }
    
    var main = shiftArgs(function(a, b, c) {
        console.log(a, b, c); // null null 1
    }, 3);