Javascript - Понимание литералов модуля Requirejs и "это"

У меня есть модуль requirejs, который я определяю без зависимостей, который я портирую из литерала объекта, который использовал раньше. Я думал, что смещение литерала, как возвращение будет работать, но он теряет ссылку на this, Я получаю ошибку Cannot call method 'getHeight' of undefined который я предполагаю, будет происходить для каждого случая this в моем объекте.

Почему это так? Из-за объема возврата? Вот что у меня есть...

define(function() {
  return {
    // Photos
    photos: {
      // Get photos wrapper
      $photos: function(){
        return $('#photos');
      },
      setHeight: function() {
        var height = this.header.getHeight(); // Here is where I get my first error "Cannot call method 'getHeight' of undefined"
        return this.$photos().height($(window).height() - height);
      },
      setWidth: function() {
        var width = 0;
        $('#photos').find('img').each(function() {
          width += parseInt($(this).width());
        });
        return this.$photos().width(width);
      },
      init: function() {
        this.setHeight();
        this.setWidth();
      }
    },
    // Header
    header: {
      $header: function() {
        return $('header')
      },
      top: function() {
        var self = this;
        return parseInt(self.$header().css('margin-top'));
      },
      bottom: function() {
        var self = this;
        return parseInt(self.$header().css('margin-bottom'));
      },
      getHeight: function() {
        return this.$header().height() + (this.top() + this.bottom());
      }
    },
    // Padd the Body
    padBody: function() {
      var padding = this.header.getHeight();
      return $('.body').css('padding-top', padding);
    },
    loadImages: function() {
      var self = this;

      $("img[data-src]").unveil(200, function() {
        $(this).load(function() {
          $(this).removeClass('loading').addClass('loaded');
          self.photos.init();
        });
      });
    },
    init: function() {
      var self = this;

      // Fire everything
      this.padBody();
      this.loadImages();

      $(window).on('resize', function() {
        self.padBody();
        self.photos.init();
      });
    }
  }
});

1 ответ

Решение

В этом случае "this" - это глобальный объект (окно или ноль в строгом режиме). Вы должны использовать конструктор ( new ...) для создания собственной области видимости для функций объекта ( jsbin.com/dubuxonu/1/edit requirejs не имеет ошибки)

Если вы не хотите конструктор - сохраните область видимости в переменной и используйте ее для вызова ваших методов в правильном контексте, как это

   (function(){
       var moduleObject = {
         meth1: function(){},
         meth2: function(){ moduleObject.meth1() }
       } 
       return moduleObject;
    });

Здесь я не использовал 'this' и прямо говорил, в каком объекте я хочу вызывать методы

Другие вопросы по тегам