steo
steo

Reputation: 4656

This referring to clicked object and not to namespace

Let's say I have a namespace and several functions , e.g. in this way :

HTML

<input type="button" class="btn" value="click">

JAVASCRIPT

var nms = {
 doAlert: function(){
     alert('doing alert');
     console.log(this);
 },
 bindBtn: function(){
     var that = this;
     $('.btn').on('click', that.doAlert);
 }

}

nms.bindBtn();

the log prints <input type="button" class="btn" value="click"> ,in other words, this refers to the element I'm executing the function in.

It is probably my lack, but I would like to understand how can I refer to nms instead of input. If possible, using this

Upvotes: 0

Views: 62

Answers (4)

nnnnnn
nnnnnn

Reputation: 150080

There are a number of ways to do this. I prefer to define the object inside an IIFE (immediately invoked function expression) so that it can use a private variable to keep track of itself:

var nms = (function () {
    var myownself = {
        doAlert: function () {
            alert('doing alert');
            console.log(myownself);
        },
        bindBtn: function () {
            $('.btn').on('click', myownself.doAlert);
        }
    };
    return myownself;
})();

nms.bindBtn();

Demo: http://jsfiddle.net/Yu5Mx/

That way, all of the methods of that object can just refer to the myownself variable but they don't need to know about the nms variable by which the object is known to the rest of your code. And if you do something like:

var temp = nms.bindBtn;
temp();

...which "messes up" the value of this within bindBtn() then it doesn't matter, because bindBtn() will still use myownself.

Note that this pattern assumes that nms will be a singleton object. If you want to be able to instantiate multiple copies you can still use the same general idea, but use a factory function or a conventional constructor function with new (rather than an IIFE).

Upvotes: 1

A. Wolff
A. Wolff

Reputation: 74420

You should use proxy() jquery's method to apply specific context:

$('.btn').on('click', $.proxy( this.doAlert, this ));

DEMO

Upvotes: 2

iConnor
iConnor

Reputation: 20209

Try this

var nms = {
 doAlert: function(){
     alert('doing alert');
     console.log(this);
 },
 bindBtn: function(){
     var that = this;
     $('.btn').on('click', function(){
        nms.doAlert.apply(that);

     });
 }

}

nms.bindBtn();

Demo

This passes that through the function as this

You can use call() for this too

Some links

apply() call();

Or Without using call or apply

var nms = {
 doAlert: function(){
     var _this = nms;
     alert('doing alert');
     console.log(_this);
 },
 bindBtn: function(){
     var that = this;
     $('.btn').on('click', nms.doAlert);
 }

}

nms.bindBtn();

Demo

Upvotes: 0

HMR
HMR

Reputation: 39320

var nms = {
 doAlert: function(){
     alert('doing alert');
     console.log(this);
 },
 bindBtn: function(){
     $('.btn').on('click', nms.doAlert.bind(nms));
 }
}

To support bind for IE you can use this

Upvotes: 0

Related Questions