Вызов метода дочернего объекта из метода родительского объекта через this

223
17 июля 2021, 20:20
(function(window, document, $, undefined){
    var InvokeWindow = function() {
        this.calcSize = function() {
            this.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
            this.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
            return this;
        };
        this.setElementXY = function(element, split, size) {
            $(element).css({
                'left': ''+(this.width / split[0] - size[0])+'px',
                'top': ''+(this.height / split[1] - size[1])+'px'
            });
            return this;
        };
    };
    var impl = {};
    impl.register = function() {
        this.invokeWindow = new InvokeWindow()
        .calcSize()
        .setElementXY('.dimension', [4, 2], [150, 150]);
        return this;
    };
    // повторный вызов после изменения размеров окна
    impl.rewrite = function() {
        this.invokeWindow
        .calcSize()
        .setElementXY('.dimension', [4, 2], [150, 150]);
        return this;
    };
    window.impl = impl;
})(window, document, jQuery);
$(function() {
    impl.register();
    var frameWait;
    $(window).resize(function() {
        clearTimeout(frameWait);
        frameWait = setTimeout(impl.rewrite, 400);
    });
});

Этот способ работает:

    impl.rewrite = function() {
        impl.invokeWindow
        .calcSize()
        .setElementXY('.dimension', [4, 2], [150, 150]);
        return this;
    };

А этот выдает ошибку "Uncaught TypeError: Cannot read property 'calcSize' of undefined":

    impl.rewrite = function() {
        this.invokeWindow
        .calcSize()
        .setElementXY('.dimension', [4, 2], [150, 150]);
        return this;
    };

В чем причина? как я могу сделать это через this?

Answer 1

Как и сказал ThisMan Проблема заключалась в потере контекста и решается с помощью bind():

frameWait = setTimeout(impl.rewrite.bind(impl), 400);
READ ALSO
Как удалить слушатель события window.matchMedia (vue)?

Как удалить слушатель события window.matchMedia (vue)?

В methods есть функция, внутри которой присваивается слушатель на windowmatchMedia()

190
Собрать объект, пройдя по элементам

Собрать объект, пройдя по элементам

Есть группа элементов, выглядят они так:

251
Slider for Bootstrap (ползунок для цен)

Slider for Bootstrap (ползунок для цен)

В интернет-магазине использую библиотеку Slider for Bootstrap, для вывода ползунка выбора диапазона цены

259