0

Take this code:

var obj = {
  init: function(){
    console.log(obj.count);
    //or 
    console.log(this.count);
  },
  count: 1,
  msg: 'hello'
}

obj.init();

I can access property of obj by this or the variable name obj both. Is there any advantage in using this ? Because in my opinion using the object name obj adds clarity to the code.

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
Jashwant
  • 28,410
  • 16
  • 70
  • 105

2 Answers2

1

The advantage of this is that it allows the same function to work for multiple instances of that type of object. The corresponding disadvantage of using the variable name obj is that it only refers to that specific instance.

In your case you've only got a singleton object since you assign your obj variable to an object literal, so there won't ever be multiple instances, but still if you later copied that code to create another similar object with a different variable name for that new object you'd have to find/replace all the uses of obj and change them to the new variable name.

Note that in JavaScript the value of this within a function depends on how the function was called, not whether the function was defined as a property/method of an object. See https://developer.mozilla.org/en/JavaScript/Reference/Operators/this.

As far as making the code readable, this is a standard part of the language that all experienced JS coders are (or should be) familiar with, and in my opinion it is more readable because you don't have to look back to see where obj was declared...

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • Inside the function, **this** will work as alias. No performance boost whatsoever. Right ? – Jashwant Jan 31 '12 at 00:19
  • 1
    Performance? I don't know. I doubt you'd notice a difference, but if I had to guess I'd say `this` would be faster since it is in effect a local variable, while use of `obj` involves tracking back up through the surrounding scope. Before you go any further working with objects I'd suggest you read the MDN page I linked to in my answer to get the full explanation of `this`... – nnnnnn Jan 31 '12 at 00:23
  • You're welcome. Obviously this is a big topic and a lot more could be said, but I tried to just mention a couple of key points that relate directly to the code you asked about. Happy coding! – nnnnnn Jan 31 '12 at 00:28
  • 1
    @nnnnnn-I think speed is irrelevant. In the example, *obj* is found on the global object. It seems that many browsers optimise global object lookups, they are extremely fast so I doubt you would see a significant performance difference vs *this* (which, as you say, is a local variable). A disadvantage of *this* is that it is set by the call, so if you call the function differently to how it expects to be called, things will break (e.g. `var b = obj.init; b()`). – RobG Jan 31 '12 at 00:38
  • Should also mention that in ES5 *this* can be set using [bind](http://es5.github.com/#x15.3.4.5). – RobG Jan 31 '12 at 00:45
  • RobG, yeap it breaks. Thanks for your time and giving a different view. This helps alot. – Jashwant Jan 31 '12 at 00:48
  • Thanks @RobG. I did mention about `this` being set by how you call the function, and gave a link to a full explanation about that. Also I said "if I had to guess" about the performance, but even without browser optimisations I wouldn't worry about performance on this unless the code is getting called thousands of times at once. Regarding what you said about globals, even if `obj` is a global variable wouldn't JS still have to check through the surrounding scope before using the global (in case there is an `obj` defined in a non-global scope)? – nnnnnn Jan 31 '12 at 00:55
  • Yes, but scope chains are usually fairly short and can be optimised by the compiler since they are fixed at the time the function is instantiated (*with* messes things up of course). Probaby another reason why eval code can be slow - compilers can't optimise it very well. – RobG Feb 01 '12 at 00:23
1

If for whatever reason you decide to pass init as a call back then the value of "this" might not what you would expect it to be.

For example if you do something like

var count = 2;
setTimeout(obj.init, 1000);

When init gets fired the console will actually log

1

2

instead of

1

1

Because the value of "this" in the init function would be binded to the global window object.

Depending on how you're calling the init function, the value of this is completely different.

obj.init() //this is binded to obj
new obj.init() //this is binded to a COPY of obj.
setTimeout(obj.init,1000); //this is binded to the global window obj
obj.init.call(obj2); //this is binded to obj2

var foo = {};
foo.bar = obj.init;
foo.bar(); //this is binded to foo;
KDV
  • 730
  • 1
  • 6
  • 12
  • +1 for pointing out issues with *this*, but in `new obj.init()`, *this* in the *init* function will be a new Object (*obj.init* is being called as a constructor), not a "copy" of *obj*. – RobG Jan 31 '12 at 00:43