22

As said here:

http://jqfundamentals.com/book/index.html

Closures can also be used to resolve issues with the this keyword, which is unique to each scope. This mechanism can be particularly useful when dealing with callbacks, though in those cases, it is often better to use Function.bind, which will avoid any overhead associated with scope traversal.

But it doesn't really say how to distinguish between the two cases. I don't understand in fact what the author means by "avoid any overhead associated with scope traversal." Can you explain?

hendalst
  • 2,957
  • 1
  • 24
  • 25
user310291
  • 36,946
  • 82
  • 271
  • 487

3 Answers3

11

What it's referring to are things like this

obj.doSomething = function() {
  var that = this;
  setTimeout(function() {
    // this is the window
    // that is the obj
    that.doSomethingElse();
  }, 50);
};

vs

obj.doSomething = function() {
  setTimeout((function() {
    // this is the obj
    this.doSomethingElse();
  }).bind(this), 50);
};

Benchmark. No noticable difference in chrome.

Raynos
  • 166,823
  • 56
  • 351
  • 396
  • 1
    Since function calls happen in microseconds and setTimeout is 10milliseconds+, isn't this lack of difference caused by setTimeout's low timing resolution? – jpillora Sep 30 '13 at 01:24
  • Yes, but which of the two is considered best practice (ie. the "nicest to read")? – Linus Unnebäck Nov 24 '13 at 20:08
  • @LinusUnnebäck that is considered personal preference. I completely avoid using `this` in JavaScript since both variants are ugly. – Raynos Nov 27 '13 at 00:43
  • 14
    Using the `this` keyword is fundamental to object oriented programming. I would recommend against the suggestion given by @Raynos. – dalgard Apr 14 '14 at 22:07
  • 1
    I find the first example nicest to read (...as long as a different variable name is used besides "that". *that*'s confusing IMO.) – Luke Jul 31 '15 at 21:32
  • 1
    @Raynos, If I would like not not use this in javascript, is there a way to do that in the above example shown? I really don't like to use this in javascript but I don't find a way to do that. – Aniruddha Das May 31 '16 at 18:45
  • A but late, but I believe in that example you could substitute the name of the object, `obj`, for `this` when calling `.doSomethingElse`. – Connor Sep 07 '16 at 15:22
  • The link to your benchmark is dead for me, but I can't see how you could get significant results when your timer is 4 or 5 orders of magnitude slower than the duration you aim to measure. – kuroi neko Jul 26 '21 at 15:48
10

Take a look at this line in the example in the link above

console.log(self.myName, this.myName);

(with self = this; a couple of lines above). The closure defined outerFunction method, exists in a different scope that is why it has a different this value from the outerObj object. (self.myName!=this.myName)

Scope traversal means, when you are reaching to grab a value (variable,object) that exists in a different scope, therefore additional overhead is added (code becomes slower to execute).

Using bind, you 're calling a function with an existing scope, so that scope traversal does not take place.

Pantelis
  • 6,086
  • 1
  • 18
  • 21
  • 3
    *code becomes slower to execute* - this is completely wrong as indicated by sbr's comment and other SO questions: http://stackoverflow.com/questions/17638305/why-is-bind-slower-than-a-closure – adelphus Jul 27 '15 at 10:45
  • Can you provide more context surrounding the line of code you added? The link provided in the original question is no longer valid. – Luke Jul 31 '15 at 21:21
  • Also, can you provide any documentation or evidence to explain "when you are reaching to grab a value that exists in a different scope, additional overhead is added". The performance check linked above by @sbr seems to show that closure is the same - even a bit faster. – Luke Jul 31 '15 at 21:29
  • 1
    Not so: self is generally faster than bind in 2015: https://jsperf.com/bind-vs-closure-setup/6 – DanHorner Aug 05 '15 at 14:19
0

jsperf is dead. meet perf.link.

i'm seeing a different victor each time i run the benchmark. my guess is, modern browsers optimize away most of the disadvantages of either of these approaches.

Trevor
  • 13,085
  • 13
  • 76
  • 99