Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using arguments pseudo-parameter as a writeable thing

In javascript, there is such thing as arguments pseudo-parameter, which allows to interact with function arguments dynamically. Now, while I'm listening to the lecture about javascript fundamental things & standards, there was a phrase:

"Don't use arguments as a writable structure, always treat is as a read-only thing"

I never used arguments to write there, so it's not a problem for me - but, really - I want to ask my

Question: are there any real use-cases when using arguments to write there is justified? If not, then why shouldn't arguments be used to write there?

like image 617
Alma Do Avatar asked Aug 14 '14 08:08

Alma Do


1 Answers

Let's suppose you're mad and you want to customize console.log so that doing

console.log("window.innerWidth");

would log

window.innerWidth = 775 

which seems more convenient than doing

console.log("window.innerWidth =", window.innerWidth);

You could do it "properly", by building a new array or you could reuse arguments :

(function(){
  var stdlog = console.log;
  console.log = function(){
    if (arguments.length===1 && typeof arguments[0]==="string") {
      try {
       arguments[1] = eval('('+arguments[0]+')');
       arguments[0] += " =";
       arguments.length = 2;
      } catch (e) {} // in case it can't be evaled, do the normal thing
    }
    stdlog.apply(console, arguments);
  };
})();

console.log("window.innerWidth"); // window.innerWidth =  775 
console.log("Hello"); // Hello

Reusing arguments here would have the advantage of not having to build an array when you don't need it and not repeating the call to stdlog. The code would be less dry without that hack.

Now, why you should not do this kind of things :

  • arguments hasn't been designed to be writable like arrays are, I had to set arguments.length explictly
  • it's rather easy to simply slice the arguments object and to pass the resulting array as no accessible function needs an arguments object anyway.
  • using a native structure in a way it was really not intended to be used may lead to future incompatibilities
  • it prevents optimizations. JS engines do a lot of optimizations without which many modern web apps wouldn't be possible. They give up optimizing in rare cases and some of them are related to arguments
  • it doesn't work the same in strict mode and not strict. Do you really want to have a function which would have a subtly different behavior if added (perhaps by concatenating files in a minification process) to a file having "use strict" ?

Here's a case in which the strict mode changes everything :

function incrNumber(v) {
  arguments[0]++;
  console.log(v)
}

In strict mode, the passed value is logged. In non strict mode, the incremented value is logged. And that's the specified behavior.

like image 154
Denys Séguret Avatar answered Nov 07 '22 13:11

Denys Séguret