0

I have code like this :

(function() {
  $(document).ready(function() {
    //event handlers
    $('.project-delete').on('click', function() {
        deleteProject($(this));
    });

    $('.keyword-delete').on('click', function() {
        deleteKeyword($(this));
  });
  this.deleteKeyword = function(model) {
    }
}).call(this);

I am curious if this is a good approach since I was learning JS recently and as far as I understand this function will have global scope, doesn't it ? since .call(this) is passing window object to this closure then I think it is not the best option ? Is there something I am missing ? Does changing .call(this) to just () change anything ?

EDIT:So is it OK to just pass window object to that closure ? Wouldn't it better to pass just a empty object or jQuery object ?

Maksym
  • 3,276
  • 3
  • 22
  • 27
  • Possibly duplicate of this question: http://stackoverflow.com/questions/8035822/why-write-callthis-at-the-end-of-an-javascript-anonyms-function – Jason Sperske Nov 08 '13 at 22:04
  • It will explicitly bind the closure's context to the parent's context. Same as `(function(){ }).apply(this)` – Josiah Ruddell Nov 08 '13 at 22:05
  • 1
    Note that I would define "scope" as being about what variables the function has access to (i.e., its own local variables plus those of any functions that it is nested inside), and that has nothing to do with the value of `this`. – nnnnnn Nov 08 '13 at 22:05
  • @nnnnnn so isn't it a better option to apply jQuery object (or maybe just empty object) to it to increase performance ? Wouldn't it increase performance if this would point to local scope ? Since window object is very slow. It is not like I need a performance here, but I am just curious if it is a good way to call this function. – Maksym Nov 08 '13 at 22:16

2 Answers2

1

Assuming this function is defined in the global scope, the deleteKeyword function will have also have global scope since this in the context of the parent function is basically window (which has been passed in as this from outside; in the global scope this === window).

If you change .call(this) to just (), this is still window inside the function. This is because when you call a function via a simple function-call, this is set to the global object, which is window.

If you want a different value for this, you will need to pass in something else via .call or .apply.

For more information about the behavior of this, take a look here.

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
1

"as far as I understand this function will have global scope, doesn't it?"

"Scope" is about what variables a function has access to (i.e., its own local variables, plus locals declared in any functions that it might be nested inside, plus global variables), and that has nothing to do with the value of this. Scope depends on where the function declaration is, but this depends on how the function is called.

"since .call(this) is passing window object to this closure"

We can't tell that just from the code shown. Presumably you mean that that block of code is not nested inside some other function, so then yes, this would be window. But if that code was ever pasted inside some other function then that this might have some other value depending on how that other function was called.

"Does changing .call(this) to just () change anything?"

If you use just () that will mean that inside the function this will be window. Whether that changes anything depends on whether the this in .call(this) was window in the first place - as I already mentioned above, if that block were nested inside some other function this could be something else. Having said that, for the code shown if this was anything other than window I think your code would break. Because you declare a function like this:

this.deleteKeyword = function(model) {...}

...and then inside the second click handler you call what I assume is meant to be the same function without using this:

deleteKeyword($(this));

The only way that will work is if this is window and the deleteKeyword() function is thus global. If this were any other object the function would be a property of that other object and thus not accessible directly as deleteKeyword(). But unless you specifically want deleteKeyword() to be accessible from other code not shown there is no reason to create it as a property of this at all. Just declare it with var:

var deleteKeyword = function(...

...and then it will be accessible only inside that function and the ones nested in it such as your click handler. And the .call() at the end of your function would be redundant since the function wouldn't ever actually use this.

"so isn't it a better option to apply jQuery object (or maybe just empty object) to it to increase performance? Wouldn't it increase performance if this would point to local scope? Since window object is very slow."

Well as I already said, "scope" and the value of this are unrelated concepts. I'm not sure why you are worrying about performance for that code. But if you were to apply jQuery or an empty object with .call(jQuery) or .call({}) the code would not work as explained above.

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • I am just more like curious about that. I just want to make use of good practices. Would it be better if i declare var that = {} an change everywhere 'this' for 'that' (also attach that in handlers)? Is it cleaner solution ? I am sorry if these questions sounds stupid, but it is pretty interesting for me. – Maksym Nov 08 '13 at 22:44
  • `var that = {}` sounds like you're just over-complicating it. Take a step back: why do you think you need to use `this` within that function at all? – nnnnnn Nov 09 '13 at 00:34