8

I have been struggling with the use of these "this" with the .bind() method and the use of the variable "self = this". In getting two different results with those, so I'm missing one concept. The case is like follow:

// Defining a callback class to use after retrieving data
var Callback = (function(){
    // UPDATED!! Local vbles
    var template_to_use, html_element, self;

    function Callback(){
        self = this,
        template_to_use = null,
        html_element = null;
    }

    var p = Callback.prototype;
    p.set_template = function(template_funct){
        self.template_to_use = template_funct;
    };

    p.set_html_element = function(html_element){
        self.html_element = html_element;
    };

    p.use_callback     = function(data){                                                              
        $(self.html_element).append(self.template_to_use(data));
    };

    return Callback;
})();

The usage of this function is like follow:

// Setup callback 1 to call after getting the data
var callback_1 = new Callback();
callback_1.set_template(use_templ_1);
callback_1.set_html_element("#list");

// Get list data
api_list.get_data(callback_1.use_callback);


// Setup callback 2 to call after getting more data
var callback_2 = new Callback();
callback_2.set_template(use_templ_2);
callback_2.set_html_element("#object");

// Get object data
api_object.get_data(callback_2.use_callback);

Two ajax calls are executed and once the get_data() function is done, they will call the callback functions that I passed to them. The issue I'm getting is that after executing those functions, the callback is always mentioning the html_element = "#object" with the corresponding template "use_templ_2".

If I use "this" and .bind function instead of the "self" vble, the results are the expected ones.

// Get object data
api_object.get_data(callback_2.use_callback.bind(callback_2));

What am I missing? It might be an error concept since even if I'm not new to js, I'm new understanding the language itself.

kitimenpolku
  • 2,222
  • 3
  • 30
  • 45
  • 2
    You're not defining the `self` variable as a local variable, so both functions are using the *same* global variable. – JJJ Nov 26 '13 at 07:33
  • First of all, don't use .bind() unless you have to use a very old version of jQuery. on() is the preferred method now. – trysis Nov 26 '13 at 07:33
  • @Juhana: looks like the `var` is missing, there are commas for all except the last one. – Qantas 94 Heavy Nov 26 '13 at 07:47
  • 2
    @trysis: that's JavaScript native `bind()` function for permanently setting the value of `this` in the function, not the deprecated jQuery `bind()` function for adding events. – Qantas 94 Heavy Nov 26 '13 at 07:49
  • @Juhana I have already updated the code to make it local but I'm still accessing to the same one. Actually, I created later a method to retrieve the "self vble". To me it is weird that when checking the object accessing to its properties the values are good, but when doing it consulting "self", both of them contains the same information. How should I initialize the self vble to avoid sharing the same content? – kitimenpolku Nov 26 '13 at 08:00
  • Sorry @kitimenpolku. I saw "bind()" & thought of jQuery. – trysis Nov 26 '13 at 17:07

2 Answers2

9

If you're asking about the difference between self and this, then self is used as a reference to the original this. That means even if the content of this is changing, then self still contains the previous.

Don't know if this is clear enough. If not take a look at What underlies this JavaScript idiom: var self = this? or Difference between self and this in javascript and when to use either of them.

Also try to avoid using self as a global variable, because it's used by browsers nowadays for something. Sorry I don't remember what for - if someone could edit this info it that would be awesome.

Community
  • 1
  • 1
Dropout
  • 12,137
  • 9
  • 47
  • 96
  • 2
    You can use `window.self` (current window) to compare to for example `window.top`. It doesn't conflict with using a local var called `self` as this will have higher priority. – Mike-O Nov 26 '13 at 08:26
3

Be careful, self will always refer to the last instanciated object :

var c1 = new Callback();
var c2 = new Callback(); // overrides previous self

Then following line actually sets c2.html_element :

c1.set_html_element(html_element);

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures

That said, replacing this is completely useless in your case.

leaf
  • 14,210
  • 8
  • 49
  • 79
  • I have been reading the link you passed me and to me, it would have sense if I'm implementing the module pattern where the vbles would be shared. I'm missing some concept but I have no idea which one. If there are two declarations, creating two objects, why are they not keeping its own values? Actually, "template_to_use" and "html_element" properties are keeping their own values but not the "self" property. – kitimenpolku Nov 26 '13 at 08:53
  • 1
    There is only one declaration wrapping the self variable, all objects actually share a common scope : `(function(){...})()`. – leaf Nov 26 '13 at 08:57
  • This is pretty hard to explain indeed, hope folks could share some better links. – leaf Nov 26 '13 at 09:00