0

I'm building a menu module. In the first file, slideout.js, I'm creating an object which has a prototype with methods toggle, open and close.

In the second file I'm trying to use that menu-module to access those methods on it's prototype, through jquery event handlers.

The problem is, that "this" in menu.toggle will now refer to the jquery object instead of the object. I understand all that.

My question is, what's the best way to solve this?
It works when doing menu.toggle.bind(menu), but that seems wrong. I could also solve it by creating an anonymous function, and then calling menu.toggle. But that seems equally wrong.

My gut says, I should fix this in slideout.js.

slideout.js

'use strict';

var proto = {
    isOpen: false,
    toggle: function() {
        return this.isOpen ? this.close() : this.open();
    },
    open: function() {
        this.isOpen = true;
        return this;
    },
    close: function() {
        this.isOpen = false;
        return this;
    }
};

module.exports = function(options) {
    var obj = Object.create(proto);

    return obj;
};

main.js

'use strict';

var slideout = require('./slideout'),
    $ = global.jQuery;

module.exports = function() {
    var menu = slideout();

    $('.js-main-menu-trigger').on('click', menu.toggle);
};
t.niese
  • 39,256
  • 9
  • 74
  • 101
ThomasM
  • 2,647
  • 3
  • 25
  • 30
  • 3
    You're going about it the wrong way, write a plugin instead that uses `$.fn` and `$.data` to store the state of each element etc. – adeneo Mar 19 '15 at 15:17
  • the fact that I'm using jquery is just to illustrate the situation, at one point I might remove jquery from the application – ThomasM Mar 19 '15 at 15:21
  • 1
    What's wrong with `menu.toggle.bind(menu)`? It does exactly what you want: it connects the `toggle` method to the context of the `menu` object. – user0815 Mar 19 '15 at 15:24
  • My point was `.bind()` is IE9 and higher – Mark Pieszak - Trilon.io Mar 19 '15 at 15:36
  • If you're using jQuery, always use [`$.proxy`](http://api.jquery.com/jQuery.proxy/) so that you don't need to juggle function references. jQuery will do that internally so you don't have to. Everywhere else, use `Function.prototype.bind`. – zzzzBov Mar 19 '15 at 15:38
  • @mcpDESIGNS: Okay, that's a point. – user0815 Mar 19 '15 at 15:38

0 Answers0