1

I know that jQuery isn't designed for working with a class-like model but I really could do with being able to extend a base class as that fits my needs perfectly.

I started by just doing the following:

jQuery.myBase = {
    foo: 'bar',
    bar: function() { ... }
}

jQuery.fn.myPlugin = function() {
   $.extend( this, jQuery.myBase, {
       oof: 'rab',
       rab: function() { ... }
  }
}

That all works fine, I can access the base methods & properties via this. That is until I try adding something like a jQuery event handler (etc.) which applies the event target to the this.

So with the following:

jQuery.myBase = {
    bar: function() { ... }
}

jQuery.fn.myPlugin = function() {
   jQuery.extend( this, jQuery.myBase, {
       init: function() {
           jQuery('#someEl').click( this.onClick );
       },

       onClick: function(e) {
           // this now references the element I bound the event to (<div id="someEl" />)
           // so the following doesn't work
           this.bar();
       }
  }
}

I've found a couple of things for class creation and inheritance that work with jQuery (such as John Resig's one and DUI) but those will/do experience the same issue.

So after all of that, how do I get to the original this in these situations?

Update: The event handler (etc.) could be in either the jQuery.myBase or the plugin itself.

4 Answers 4

2

You need a reference to it in the appropriate scope.

jQuery.fn.myPlugin = function() {
   var $this = this;  // Scope it up!
   jQuery.extend( this, jQuery.myBase, {
       init: function() {
           jQuery('#someEl').click( this.onClick );
       },

       onClick: function(e) {
           $this.bar();
       }
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I should have mentioned that I already tried that and it kind of works, but what if the event were in the jQuery.myBase definition? That still has no access to $this.
0

The only way that I've thought of doing this, which I don't really like and thus asking the question, is with the following:

jQuery.myBase = {
    bar: function() { ... }
}

jQuery.fn.myPlugin = function() {
   jQuery.extend( this, jQuery.myBase, {
       init: function() {
           var self = this;
           jQuery('#someEl').click( function(e) {
                this.onClick.apply( self, arguments );
           };
       },

       onClick: function(e) {
           // this works
           this.bar();
       }
  }
}

Comments

0

Another alternative would be to follow prototypes method of having a bind() function (which actually does the same as my other answer but in a cleaner fashion), as pointed out in this question, e.g.:

if (!Object.bind) {
    Function.prototype.bind= function(owner) {
        var that= this;
        var args= Array.prototype.slice.call(arguments, 1);
        return function() {
            return that.apply(owner,
                args.length===0? arguments : arguments.length===0? args :
                args.concat(Array.prototype.slice.call(arguments, 0))
            );
        };
    };
}


jQuery.fn.myPlugin = function() {
   jQuery.extend( this, jQuery.myBase, {
       init: function() {
           jQuery('#someEl').click( this.onClick.bind( this ) );
       },

       onClick: function(e) {
           this.bar(); // this works
       }
  }
}

Comments

0

It looks like they are addressing this in jQuery which should be part of 1.3.3 according to the comments

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.