-1

The Problem

In my "private" object for the facade pattern, I am defining methods and properties. When calling a method in this "private" object, I am getting Uncaught Typerror's saying that the method I am calling is not a function.

The Code

    var lazySize = (function() {

        var _ = {
            images: [],

            lazySizes: {},

            resizeTimeout: null,

            pageWidth: document.getElementsByClassName('crop_image')[0].offsetWidth,

            resizeHandler: function() {
                var i = 0;
                for (var image in this.lazySizes) {
                    if (this.pageWidth < image) {
                        this.images[i++].src = this.lazySizes[image];
                    }
                }
            },

            resizeThrottler: function() {
                if (!this.resizeTimeout) {
                    this.resizeTimeout = setTimeout(function() {
                        this.resizeTimeout = null;
                        this.resizeHandler();
                    }, 66);
                }
            }
        };

        return {
            init: function() {
                window.addEventListener('resize', _.resizeThrottler, false);
            }
        };

    }());

lazySize.init();

The Error

Uncaught TypeError: this.resizeHandler is not a function

The Question

Why am I unable to access the resizehandler method while inside resizeThrottler?

My understanding when using var rather than let, is that JavaScript is function scoped, so I am rather puzzled as to why I can't access it.

I am trying to improve my JavaScript, so if I am doing something really bad here, I would be very grateful if someone could point it out.

jayrue
  • 151
  • 1
  • 11
  • I feel that you unfairly marked this as duplicate. My question is specific to this design pattern, the link you provided does not even have an accepted answer. This suggestion trincot gave helped me resolve this issue AND also offered a help ful explanation. Please take back your duplicate flag. – jayrue Nov 13 '15 at 18:28

1 Answers1

2

This is because this does not correspond to what you think it does.

You pass the resizeThrottler method as a reference for the browser to call, but when it does call it, the context is no longer your object, but window, which evidently does not have the same properties.

You could solve this as follows:

 window.addEventListener('resize', _.resizeThrottler.bind(_), false);

This way you set the context of the method passed as handler to always run with _ as this.

trincot
  • 317,000
  • 35
  • 244
  • 286