Search code examples
javascriptcachingclosuresmemoization

Javascript: Caching within Closure doesn't work


I am trying to cache the result of the variable "url" in APP.findUrlParameter(). When executing the function the 2nd time, url should not be undefined anymore, but unfortunately it is.

example url: mypage.com?test=123&name=tom

(function () {
var APP = {

    urlParameterPairs: function () {

        var url;  


        if (window.location.search) {
            url = window.location.search;
            url = url.substring(1).split('&');
            $.each(url, function (i) {
                url[i] = url[i].split('=');
            });
        }
        return url;
    },

    findUrlParameter: function (key) {
        var url; // <---- to be cached !
        console.log(url);

        return (function () {
            var result; 

            url = url || APP.urlParameterPairs();
            $.each(url, function (i) {
                var pair = url[i];
                if (pair[0] === key) {
                    result = pair[1];
                    return false;
                }
            });
            return result;
        }());
    }
};
console.log('name: ' + APP.findUrlParameter('name'));
console.log('test: ' + APP.findUrlParameter('test'));
}());

logs:

  • undefined
  • name: tom
  • undefined
  • test: 123

expected:

  • undefined
  • name: tom
  • Array: ["name", "tom"],["test", "123"]
  • test: 123

Solution

  • Thanks for the answers, of course "url" gets redeclared, stupid me didn't notice. I could solve it with wrapping a closure around it and returning a function like this:

    findUrlParameter: (function () {
            var url;
    
            function f(key) {
                var result;
    
                url = url || APP.urlParameterPairs();
                $.each(url, function (i) {
                    var pair = url[i];
                    if (pair[0] === key) {
                        result = pair[1];
                        return false;
                    }
                });
                return result;
            }
            return f;
        }())