Search code examples
javascriptarraysjoinprototypecall

Regarding with JavaScript array prototype


I have recently read tutorial associated with JavaScript from this page, I tried some piece of code but i didn't understand some logic. Below is author code.

function itself:

var lz="";
lz.memo = function (fn) {
var cache = {};
return function () {
    var key = [].join.call(arguments, '§') + '§';
    if (key in cache) {
        return cache[key];        }
    return cache[key] = fn.apply(this, arguments);
  };
};

and its execution

 var foo = 1;
function bar(baz) {
    return baz + foo;
}
var cached = lz.memo(bar);
console.log(cached(1));
foo += 1;
console.log(cached(1)); //2

But if I change

var key = [].join.call(arguments, '§') + '§';

to

var key=arguments[0];

it also works (Caching works). What is the purpose here the author used

var key = [].join.call(arguments, '§') + '§';

Thank for attention! Here is CODEPEN of code


Solution

  • it also works (Caching works)

    Only because you called it with just one argument. (And it didn't quite work the same way, the cache key will be missing the § on the key that the original code had.)

    What is the purpose here the author used

    They're creating a string with all of the arguments you supply joined together with § between them and § at the end, like this:

    function foo() {
      return [].join.call(arguments, '§') + '§';
    }
    console.log(foo(1)); // 1§
    console.log(foo(1, 2)); // 1§2§
    console.log(foo("a", "b", "c")); // a§b§c§

    They're doing it because arguments is array-like, but it isn't an array, and so it doesn't have the join method from Array.prototype.

    There's actually no reason for the temporary array they create, you can just call join directly:

    return Array.prototype.join.call(arguments, '§') + '§';
    

    Another opton is to convert arguments to an actual array:

    return Array.prototype.slice.call(arguments).join('§') + '§';
    

    Or in ES2015 (or with a shim):

    return Array.from(arguments).join('§') + '§';