I needed to join a function’s arguments using array.join() and
I remembered that I could not simply call join() on the
arguments object, as it is not a real array.
Internet wisdom has it that arguments can be changed into an
Array by this code snippet:
1const args = Array.prototype.slice.call (arguments);
Slicing can cost much more than expected
It came as a surprise to me, when I found this warning in the
MDN documentation
for arguments:

The JavaScript interpreter in modern browsers is doing lots of optimizations,
which are turned off if arguments is leaked outside of a function.
Leaking arguments happens in following cases:
- When the function returns
arguments. - When the function passes
argumentsto another function (such ascall()in the classicArray.prototype.slice.call(arguments)). - When
argumentsget captured in a closure.
See Petka Antonov’s explanation.
Workaround
The solution is to create an array with the expected size, and then copy one item after the other.
Here is a working example:
1const args = new Array (arguments.length);
2for (var i = 0; i < args.length; ++i) {
3 args[i] = arguments[i];
4}
and obviously, you should not extract this piece of code when doing some refactoring, as you’d end up with leaking again, defeating the purpose of this code snippet.
EDIT: see this follow-up post for the idiomatic ES2015 way of writing equivalent code.