0

I'm using the Object.init pattern in my application. Where within the init i initialize variables attached to the object, for example:

var MyObject = {

 init: function() {
   this.element = $('.someElement');


   this.element.bind('click', this._doSomething.bind(this));
 },

 _doSomething = function() {
    // METHOD WHICH I WILL MANIPULATE THIS.ELEMENT

 }

};

What i'm trying to know is, if i have to create some variables inside the method _doSomething, should i attach the variables to the MyObject with this, like this:

this.someVar = 'something';

Or should i use var:

var someVar = 'something';

I think the best way is use this if i will use the someVar in other parts of MyObject, and i should var if i use only in the scope of _doSomething method.

But this is my opinion, i want know the best practice.

Thanks.

  • Well, would you have your variable to be accesible or not? Attaching a property to the object makes it "public". – MinusFour Aug 19 '15 at 01:36
  • Use a closure (to capture the "current context" or element); use `Function.bind`; or use the additional event data with the jQuery handler. – user2864740 Aug 19 '15 at 01:36
  • 2
    `"I think the best way is use this if i will use the someVar in other parts of MyObject, and i should var if i use only in the scope of _doSomething method."` - That sounds about right! – Jack Aug 19 '15 at 01:36
  • 1
    `this.element.bind('click', this._doSomething.bind(this))` – elclanrs Aug 19 '15 at 01:41

2 Answers2

-1

Your presumption is correct; use this.myVar for anything with a lifetime longer than one function.

To give you a better idea of how this works, your object can associate a string key like "myVar" with a variable. this.myVar is shorthand for this["myVar"]. Might look a little weird, but that's standard for setting/retrieving JS properties.

However, var myVar declarations are not associated with any one object; they survive for the lifetime of the function. They can be preserved if you have a function inside of a function, but that's not what you were asking about. If you are curious though, look up the term "closures".

Katana314
  • 8,429
  • 2
  • 28
  • 36
  • So it is correct to say that using 'var' the performance will be better? –  Aug 19 '15 at 01:41
  • @Amanda Ferrari, not really... it will provide some sort of encapsulation. – MinusFour Aug 19 '15 at 01:43
  • This will not solve the OPs problem - which is that `this` in the jQuery callback will not be that of the object. Also, the OP already has `this.element` .. – user2864740 Aug 19 '15 at 01:44
  • but if the lifetime is shorter using var, this means that the garbage collector will throw it away, no? –  Aug 19 '15 at 01:44
  • It will be left for the GC to pick it up yes, however by doing assignments every time you call the function you are also wasting some resources. – MinusFour Aug 19 '15 at 01:47
  • Hm interesting @MinusFour.. so, thinking about performance, what is the best choice here if i'm going to call just one time? –  Aug 19 '15 at 01:49
  • @user2864740 Maybe you saw an earlier edit than me, but I don't see anything wrong; `this` will have the same reference during either function. @Amanda - If you're beginning with JavaScript, don't concern yourself too too much with performance. `var`s will be local and temporary, making sense for certain things if you only need them a short time. – Katana314 Aug 19 '15 at 01:51
  • @Katana314 It will *not* 'have the same `this` object' - because the method (used as a generic callback) is invoked via *jQuery's* event binding (`$.bind` is not to be confused with `Function.prototype.bind`). – user2864740 Aug 19 '15 at 05:25
  • @Katana314 The `this` in the callback should be the DOM element itself that is the even target (but not the object with the `element` property; and not the jQuery object). – user2864740 Aug 19 '15 at 05:26
  • @user2864740 First, JQuery will invoke its `$().bind` handler. This will have the DOM element as the `this` element. However, the handling function it then calls is the correct `Function.prototype.bind`-bound function, so it will call that method with the MyObject`this` context. IF the line were written as `this.element.bind('click', this._doSomething);`, then you would be correct. – Katana314 Aug 19 '15 at 15:45
-1

The fact you named your function _doSomething, tells me it's a candidate for an IIFE. It's not accessible to the outside and you can interface with your object using foo.init();

Edit: changed listener, as per comment

jsfiddle

var foo = (function(){

    // private function
    function doSomething() {
    // METHOD WHICH I WILL MANIPULATE THIS.ELEMENT
        alert('doSomething()');
    }

    var myObject = {
        init: function() {
            this.message = 'hello init';
            this.element = $('.someElement');
            this.element.on('click', function() { doSomething.call(this); }.bind(this));
            alert(this.message);
        }
    };

    return myObject;

})();

foo.init();
Community
  • 1
  • 1
Data
  • 1,337
  • 11
  • 17
  • Using `Function.call` will result in `doSomething` being called right away and is equivalent to writing `this.element.bind('click', doSomething(this))`. – user2864740 Aug 19 '15 at 01:47
  • 1
    The extra function is not needed and looks like it muddling up use of a (non used) closure. Just use `this.element.on('click', doSomething.bind(this));` – user2864740 Aug 19 '15 at 05:29